Latest Posts (20 found)
iDiallo Today

That's it, I'm cancelling my ChatGPT

Just like everyone, I read Sam Altman's tweet about joining the so-called Department of War, to use ChatGPT on DoW classified networks. As others have pointed out, this is the entry point for mass surveillance and using the technology for weapons deployment. I wrote before that we had the infrastructure for mass surveillance in place already, we just needed an enabler. This is the enabler. This comes right after Anthropic's CEO wrote a public letter stating their refusal to work with the DoW under their current terms. Now Anthropic has been declared a public risk by the President and banned from every government system. Large language models have become ubiquitous. You can't say you don't use them because they power every tech imaginable. If you search the web, they write a summary for you. If you watch YouTube, one appears right below the video. There's a Gemini button on Chrome, there's Copilot on Edge and every Microsoft product. There it is in your IDE, in Notepad, in MS Paint. You can't escape it. Switching from one LLM to the next makes minimal to no difference for everyday use. If you have a question you want answered or a document to summarize, your local Llama will do the job just fine. If you want to compose an email or proofread your writing, there's no need to reach for the state of the art, any model will do. For reviewing code, DeepSeek will do as fine a job as any other model. A good use of ChatGPT's image generator. All this to say, ChatGPT doesn't have a moat. If it's your go-to tool, switching away from it wouldn't make much of a difference. At this point, I think the difference is psychological. For example, my wife once told me she only ever uses Google and can't stand any other search engine. What she didn't know was that she had been using Bing on her device for years. She had never noticed, because it was the default. When I read the news about OpenAI, I was ready to close my account. The only problem is, well, I never use ChatGPT. I haven't used it in years. My personal account lay dormant. My work account has a single test query despite my employer trying its hardest to get us to use it. But I think none of that matters when OpenAI caters to a government agency with a near-infinite budget. For every public account that gets closed, OpenAI will make up for it with deeper integration into classified networks. Not even 24 hours later, the US is at war with Iran. So while we're at it, here is a nice little link to help you close your OpenAI account .

0 views

Daemon: a 2006 techno-thriller that reads like a 2026 product roadmap

Fair warning: this post contains spoilers for both Daemon and Freedom™. Then again, the books came out twenty years ago. If you haven’t read them by now, you probably weren’t going to. I highly recommend them both though, if you haven’t read them yet. I finished re-reading Daniel Suarez’s Daemon and its sequel Freedom™ a few weeks ago. I first picked them up years back and thought they were solid techno-thrillers with some wild ideas baked into an entertaining plot. Reading them again in 2026, they’re just as gripping, but for somewhat different reasons. The realism has caught up in a way I wasn’t expecting. When I first read these books, I took them as clever speculation of what the future may look like. Now I’m reading them and thinking: yeah, that exists. That too. And that. The fiction hasn’t aged, the real world has just gone ahead and built most of it. The premise is straightforward: Matthew Sobol, a dying game developer, leaves behind a distributed AI program that activates after his death. The Daemon, as it’s called, begins infiltrating systems, recruiting operatives through an online game-like interface, and systematically restructuring society. In Freedom™ , the sequel, that restructuring plays out in full: decentralised communities, alternative economies, mesh networks, and a population split between those plugged into the new system and those clinging to the old one. Suarez self-published Daemon in 2006. That bears repeating. 2006. YouTube was a year old. The iPhone didn’t exist yet. And this guy was writing about autonomous vehicles, augmented reality glasses, voice-controlled AI agents, distributed botnets acting with real-world consequences, and desktop fabrication units. Not as far-future sci-fi set in 2150, but as things that were five to ten years away. The Daemon’s entire existence starts with what is essentially a cron job. Sobol’s program sits dormant, scraping news headlines, waiting for a specific trigger: reports of his own death. When it finds them, it wakes up and starts executing. It wasn’t a sentient AI gone rogue with a dramatic moment it becomes into being. Just a script polling RSS feeds on a schedule, pattern-matching against text, and firing off the next step in a chain. I had something similar with OpenClaw for a while. Not the assassinations, obviously, but the same fundamental architecture of scheduled tasks that wake up, pull information from the internet, process it, and take action without any human prompting. Morning briefings, inbox sweeps, periodic research jobs. The Daemon’s trigger mechanism felt sinister in 2006. Now it’s a feature you can configure in a YAML file. Yep, I know what you’re thinking - we’ve had cron for a long time and this part was possible even before the book was written - but this is just the first chapter of the book. Then there are the autonomous machines. Sobol’s Daemon deploys “AutoM8s”: driverless vehicles that transport operatives and, in the book’s darker moments, act as weapons. It also uses robotic ground units for surveillance and enforcement. In 2006, this was pure fiction. Now Boston Dynamics has Spot, a quadruped robot dog that autonomously navigates terrain, avoids obstacles, and self-charges. Their Atlas humanoid can do backflips, parkour courses, and 540-degree inverted flips. These are real machines you can watch on YouTube doing things that would have read as absurd twenty years ago. Suarez’s vision of autonomous robots patrolling and operating independently isn’t a prediction anymore, it’s a product catalogue. The always-connected vehicle is another one. In Daemon, the AutoM8s are permanently networked, receiving instructions and sharing data in real time. Every Tesla on the road today is essentially this. Always online, streaming telemetry back to the mothership, receiving over-the-air updates, and feeding its camera data into a collective neural network. The car you’re driving is a node in someone else’s distributed system. Sobol would have appreciated the irony of people voluntarily buying into that. One of the creepier technologies in the books is WiFi-based surveillance, using wireless signals to detect and track people through walls. Suarez wrote about this as a covert capability the Daemon could exploit. Carnegie Mellon researchers have since built exactly that. Their “DensePose from WiFi” system uses standard WiFi router signals to reconstruct human poses in real time, even through solid walls. The reflected signals carry enough information about body shape and movement that a neural network can map what you’re doing in a room without a single camera. It works through drywall, wood, and even concrete up to a point, and none of this is classified military tech. It’s published academic research that anyone can read. The acoustic weapon is probably the one that catches people off guard the most. In Daemon, there’s a directed sound system that can make audio appear to come from right beside you while no one else in the room hears a thing. It sounds like science fiction until you look up parametric speakers. Companies like Holosonics have been selling “Audio Spotlight” systems for years. They work by emitting “modulated ultrasonic beams that demodulate into audible sound only within a tight, targeted area” - I’ve experienced these in airports, but have no idea what that quote actually means. Museums, airports, and retailers already use them, and the military has explored them for crowd control. The effect is exactly what Suarez described, sound that seems to materialise out of thin air, audible only to the person standing in the beam, and you can buy one commercially right now. The social dynamics might be the most on-the-nose parallel of all. In the books, the Daemon recruits human operatives to carry out tasks in the physical world. It finds people, assigns them work, and pays them through its own system. The humans don’t fully understand the bigger picture. They just complete their tasks and collect their reward. In January 2026, a site called RentAHuman.ai launched. It’s a platform where OpenClaw AI agents can hire actual people to perform tasks for them. Humans sign up with their skills and hourly rate, AI agents post jobs, and people complete them for payment in stablecoins. Over 40,000 people registered within days. The framing is different, obviously. It’s gig work, not a shadowy network of mindless humans - arguably. But the underlying structure is identical. AI systems delegating physical-world tasks to human operatives who sign up voluntarily, motivated by compensation and a sense of participation in something larger. Suarez wrote it as dystopian fiction that, in 2006 seemed like only the insane would enroll. We built it as a startup and it got very popular, very quickly. The 10% that hasn’t happened is mostly about scale and centralisation. Sobol’s Daemon is a single, coherent system with an architect’s intent behind every action. Real distributed systems don’t work like that. AI development has been messy, competitive, and fragmented across hundreds, perhaps even thousands, of companies and research labs. There’s no singular Daemon pulling strings, just a chaotic landscape of overlapping systems with no one fully in control. Which, depending on your perspective, might actually be worse. The weaponised autonomous vehicles haven’t materialised in the way Suarez imagined either, though military drones certainly have. The line between his fiction and real-world drone warfare is thinner than most people would be comfortable with. And the neat resolution in Freedom™ , where Darknet communities build something genuinely better, still feels like the most fictional part of the whole thing. We’ve got the decentralised technology. We’ve got the mesh networks and the alternative currencies. What we haven’t got is the social cohesion to do anything coherent with them. Crypto became a speculative casino with massive peaks and equal troughs. The tools exist, but the utopian bit remains out of reach. Suarez wasn’t writing from some academic ivory tower or speculating about technology he’d never touched. He was an IT consultant who spent years working with Fortune 1000 companies, and you can feel that experience on every page. He understood how systems actually work, how they fail, and how they get exploited, which is what makes re-reading both books such a strange experience. He wasn’t guessing at any of this. He was extrapolating from things he could already see forming, and doing it with an accuracy that I genuinely wouldn’t have believed twenty years ago. If you haven’t read Daemon and Freedom™ , go and read them. I track everything I read on Hardcover , and both of these are easy five-star picks. They’re fantastic books on their own merits. The pacing is relentless, the technical detail is sharp without being dry, and the plot keeps pulling you forward. I’d recommend them even if none of the technology had come true. But it has, and not gradually over twenty years. The pace is accelerating. Half the parallels I’ve listed in this post didn’t exist even twelve months ago. OpenClaw’s cron system, RentAHuman.ai, the latest generation of Boston Dynamics robots: all 2025 or 2026 developments. The gap between Suarez’s fiction and our reality is closing faster each year, and that makes the books hit differently every time you revisit them. I suspect they’ll hit differently again in another twelve months, and I can’t wait to re-read them then.

0 views
Pete Warden Yesterday

Launching a free, open-source, on-device transcription app

TL;DR – Please try Moonshine Note Taker on your Mac! For years I’ve been telling people that AI wants to be local, that on-device models aren’t just a poor man’s alternative to cloud solutions, and that for some applications they can actually provide a much better user experience. It’s been an uphill battle though, because models all start in a datacenter and using cloud APIs is often so much easier for developers. There was a saying at Google that a picture is worth a thousand words, but a working demonstration is worth a thousand pictures, so with the release of the new Moonshine models I decided to show the advantages in a tangible way. As a CEO my primary job seems to be joining meetings to nod sagely along while I try to figure out what’s going on, and to remember what we decided in previous meetings. Like a lot of people whose job involves this kind of work, I’ve found AI meeting note taking and transcription apps increasingly useful, but I kept wishing the user experience was better: I was also frustrated as an engineer that using the cloud for this use case was an inelegant solution. Speech to text deserves to be a core operating system function, just like keyboard drivers, and using the cloud adds unneeded complexity. To address these issues, I’ve just released the first version of Moonshine Note Taker , for Macs. If you get a chance, please give it a try and let me know what you think. I’m hoping this will be a tangible demonstration of the power of local AI, and inspire more integrations of the Moonshine framework into new and existing applications, so feedback will help a lot. It was often hard to correct or format the transcriptions, especially during meetings. The results would end up on a website I’d have to log into, or in my inbox, when I usually just want to save them on my laptop. Even if an app gave me a live view, there was usually a long delay before text appeared, and it didn’t update very frequently. I found trying to review the notes afterwards more difficult than it needed to be. I often wanted to hear the recording for an important sentence to help my understanding, and most apps don’t let you do that. Trusting a startup to store and protect very sensitive conversations makes me nervous. Servers full of thousands of people’s meetings are always going to be tempting targets for hackers, and you never know when a startup’s business model will change. I already have a thousand subscriptions, keeping track of them is a pain, and there were often usage limits even when I did pay. You can edit and lay out the notes as people are talking with no delay, and using a familiar native Apple interface. The results are . files that you save just like any other document, locally on your machine, never touching the cloud. The transcriptions show up almost instantaneously. Audio is saved alongside the transcription, and playing back a particular section is as simple as selecting the text or moving the caret and pressing the play button. There is absolutely no connection to the cloud. All data is kept entirely on your drive, and can be deleted instantly whenever you decide. Because it’s local, your app will never be bricked by an acquisition or pivot either. Because I don’t have to pay server costs, I can afford to make this free and open source without losing money, and I’ll never have to impose usage limits.

0 views
Jim Nielsen Yesterday

Computers and the Internet: A Two-Edged Sword

Dave Rupert articulated something in “Priority of idle hands” that’s been growing in my subconscious for years: I had a small, intrusive realization the other day that computers and the internet are probably bad for me […] This is hard to accept because a lot of my work, hobbies, education, entertainment, news, communities, and curiosities are all on the internet. I love the internet, it’s a big part of who I am today Hard same. I love computers and the internet. Always have. I feel lucky to have grown up in the late 90’s / early 00’s where I was exposed to the fascination, excitement, and imagination of PCs, the internet, and then “mobile”. What a time to make websites! Simultaneously, I’ve seen how computers and the internet are a two-edged sword for me: I’ve cut out many great opportunities with them, but I’ve also cut myself a lot (and continue to). Per Dave’s comments, I have this feeling somewhere inside of me that the internet and computers don’t necessarily align in support my own, personal perspective of what a life well lived is for me . My excitement and draw to them also often leave me with a feeling of “I took that too far.” I still haven’t figured out a completely healthy balance (but I’m also doing ok). Dave comes up with a priority of constituencies to deal with his own realization. I like his. Might steal it. But I also think I need to adapt it, make it my own — but I don’t know what that looks like yet. To be honest, I don't think I was ready to confront any of this but reading Dave’s blog forced it out of my subconscious and into the open, so now I gotta deal. Thanks Dave. Reply via: Email · Mastodon · Bluesky

0 views
Stratechery Yesterday

2026.09: This Was an Xbox

Welcome back to This Week in Stratechery! As a reminder, each week, every Friday, we’re sending out this overview of content in the Stratechery bundle; highlighted links are free for everyone . Additionally, you have complete control over what we send to you. If you don’t want to receive This Week in Stratechery emails (there is no podcast), please uncheck the box in your delivery settings . On that note, here were a few of our favorites this week. This week’s Stratechery video is on Thin Is In . From Owning the Living Room to Ceding the Hardware Market ? After Phil Spencer’s exit at Microsoft,  Wednesday’s Daily Update provided an entertaining tour of Xbox history , including strategy that has been misaligned for at least 15 years, and why some of those red flags were ignored at the time (spoiler: “[Microsoft] held onto Xbox as the sole piece of evidence that the company could be cool and interesting to consumers”). Today, though, there are new pivots to discuss. So what’s next? Ben builds on the fraught history to explain why, given the lack of growth in the gaming market and competitive pressures on the rest of Microsoft’s business, the days of 1st party Xbox hardware may be over.  — Andrew Sharp From MJ to Wemby and Everything in Between. With Andrew on vacation, Greatest of All Talk was lucky to have the illustrious Rachel Nichols on as a guest. From sharing stories from her early days as an intern covering Michael Jordan to reflecting on the end of the Washington Post Sports section and the changing media landscape, Rachel’s unique experience provided a compelling through line across eras of sports and media. Come for the discussion of whether Wemby and the Spurs can win it all, stay for the greatest moose related headline of all time. — Ben Thompson It’s Time to Build… In Space?  In 2016 Jeff Bezos said, “We can build gigantic chip factories in space.” 10 years later, with chip constraints  as urgent as ever , a number of companies are already exploring manufacturing in space (data centers, pharmaceuticals), so why not chips too?  This week’s Asianometry video  answers that question comprehensively, noting that LEO chip fabbing would impose incredible logistics challenges (cooling, cleaning, managing radiation, constant maintenance  in space ), and would probably require reimagining the entire chip stack (how do you handle packaging in space?). It’s a great, itemized breakdown of the obstacles —  available as a podcast or transcript for Stratechery Plus subscribers  — that also underscores how many incredible challenges we’ve already solved on earth. — AS Another Viral AI Doomer Article, The Fundamental Error, DoorDash’s AI Advantages — Another AI doomer article has gone viral, and like many in the genre, it lacks an appreciation for dynamism and markets. Then, why DoorDash is going to be fine. Xbox Replaces Head of Gaming, Xbox History, Whither Xbox — Xbox has a new head, who isn’t a gamer; I suspect Microsoft is doing what it should have done a decade ago: get out of the console business. An Interview with Bill Gurley About Runnin’ Down a Dream — An interview with long-time (retired) VC Bill Gurley about his new book about building a career you love, Uber, and the modern state of VC. AI Xbox Doom Privacy Screens and Apple Report Cards Chip Fabs in Space: Technically Possible, Completely Impractical The GOAT pod visits No Dunks Rachel Nichols on Mike, WaPo, Luka & Wemby

0 views

Premium: The Hater's Guide to Private Equity

We have a global intelligence crisis, in that a lot of people are being really fucking stupid. As I discussed in this week’s free piece , alleged financial analyst Citrini Research put out a truly awful screed called the “2028 Global Intelligence Crisis” — a slop-filled scare-fiction written and framed with the authority of deeply-founded analysis, so much so that it caused a global selloff in stocks .  At 7,000 words, you’d expect the piece to have some sort of argument or base in reality, but what it actually says is that “AI will get so cheap that it will replace everything, and then most white collar people won’t have jobs, and then they won’t be able to pay their mortgages, also AI will cause private equity to collapse because AI will write all software.”  This piece is written specifically to spook *and* ingratiate anyone involved in the financial markets with the idea that their investments are bad but investing in AI companies is good, and also that if they don't get behind whatever this piece is about (which is unclear!), they'll be subject to a horrifying future where the government creates a subsidy generated by a tax on AI inference (seriously). And, most damningly, its most important points about HOW this all happens are single sentences that read "and then AI becomes more powerful and cheaper too and runs on a device."  Part of the argument is that AI agents will use cryptocurrency to replace MasterCard and Visa. It’s dogshit. I’m shocked that anybody took it seriously. The fact this moved markets should suggest that we have a fundamentally flawed financial system — and here’s an annotated version with my own comments. This is the second time our markets have been thrown into the shitter based on AI booster hype. A mere week and a half ago, a software sell-off began because of the completely fanciful and imaginary idea that AI would now write all software . I really want to be explicit here: AI does not threaten the majority of SaaS businesses, and they are jumping at ghost stories.  If I am correct, those dumping software stocks believe that AI will replace these businesses because people will be able to code their own software solutions. This is an intellectually bankrupt position, one that shows an alarming (and common) misunderstanding of very basic concepts. It is not just a matter of “enough prompts until it does this” — good (or even functional!) software engineering is technical, infrastructural, and philosophical, and the thing you are “automating” is not just the code that makes a thing run.  Let's start with the simplest, and least-technical way of putting it: even in the best-case scenario, you do not just type "Build Be A Salesforce Competitor" and it erupts, fully-formed, from your Terminal window. It is not capable of building it, but even if it were, it would need to actually be on a cloud hosting platform, and have all manner of actual customer data entered into it. Building software is not writing code and then hitting enter and a website appears, requiring all manner of infrastructural things (such as "how does a customer access it in a consistent and reliable way," "how do I make sure that this can handle a lot of people at once," and "is it quick to access," with the more-complex database systems requiring entirely separate subscriptions just to keep them connecting ).  Software is a tremendous pain in the ass. You write code, then you have to make sure the code actually runs, and that code needs to run in some cases on specific hardware, and that hardware needs to be set up right, and some things are written in different languages, and those languages sometimes use more memory or less memory and if you give them the wrong amounts or forget to close the door in your code on something everything breaks, sometimes costing you money or introducing security vulnerabilities.  In any case, even for experienced, well-versed software engineers, maintaining software that involves any kind of customer data requires significant investments in compliance, including things like SOC-2 audits if the customer itself ever has to interact with the system, as well as massive investments in security.  And yet, the myth that LLMs are an existential threat to existing software companies has taken root in the market, sending the share prices of the legacy incumbents tumbling. A great example would be SAP, down 10% in the last month.  SAP makes ERP (Enterprise Resource Planning, which I wrote about in the Hater's Guide To Oracle ) software, and has been affected by the sell-off. SAP is also a massive, complex, resource-intensive database-driven system that involves things like accounting, provisioning and HR, and is so heinously complex that you often have to pay SAP just to make it function (if you're lucky it might even do so). If you were to build this kind of system yourself, even with "the magic of Claude Code" (which I will get to shortly), it would be an incredible technological, infrastructural and legal undertaking.  Most software is like this. I’d say all software that people rely on is like this. I am begging with you, pleading with you to think about how much you trust the software that’s on every single thing you use, and what you do when a piece of software stops working, and how you feel about the company that does that. If your money or personal information touches it, they’ve had to go through all sorts of shit that doesn’t involve the code to bring you the software.  Any company of a reasonable size would likely be committing hundreds of thousands if not millions of dollars of legal and accounting fees to make sure it worked, engineers would have to be hired to maintain it, and you, as the sole customer of this massive ERP system, would have to build every single new feature and integration you want. Then you'd have to keep it running, this massive thing that involves, in many cases, tons of personally identifiable information. You'd also need to make sure, without fail, that this system that involves money was aware of any and all currencies and how they fluctuate, because that is now your problem. Mess up that part and your system of record could massively over or underestimate your revenue or inventory, which could destroy your business. If that happens, you won't have anyone to sue. When bugs happen, you'll have someone who's job it is to fix it that you can fire, but replacing them will mean finding a new person to fix the mess that another guy made.  And then we get to the fact that building stuff with Claude Code is not that straightforward. Every example you've read about somebody being amazed by it has built a toy app or website that's very similar to many open source projects or website templates that Anthropic trained its training data on. Every single piece of SaaS anyone pays for is paying for both access to the product and a transfer of the inherent risk or chaos of running software that involves people or money. Claude Code does not actually build unique software. You can say "create me a CRM," but whatever CRM it pops out will not magically jump onto Amazon Web Services, nor will it magically be efficient, or functional, or compliant, or secure, nor will it be differentiated at all from, I assume, the open source or publicly-available SaaS it was trained on. You really still need engineers, if not more of them than you had before. It might tell you it's completely compliant and that it will run like a hot knife through butter — but LLMs don’t know anything, and you cannot be sure Claude is telling the truth as a result. Is your argument that you’d still have a team of engineers (so they know what the outputs mean), but they’d be working on replacing your SaaS subscription? You’re basically becoming a startup with none of the benefits.  To quote Nik Suresh, an incredibly well-credentialed and respected software engineer (author of I Will Fucking Piledrive You If You Mention AI Again ), “...for some engineers, [Claude Code] is a great way to solve certain, tedious problems more quickly, and the responsible ones understand you have to read most of the output, which takes an appreciable fraction of the time it would take to write the code in many cases. Claude doesn't write terrible code all the time, it's actually good for many cases because many cases are boring. You just have to read all of it if you aren't a fucking moron because it periodically makes company-ending decisions.” Just so you know, “company-ending decisions” could start with your vibe-coded Stripe clone leaking user credit card numbers or social security numbers because you asked it to “just handle all the compliance stuff.” Even if you have very talented engineers, are those engineers talented in the specifics of, say, healthcare data or finance? They’re going to need to be to make sure Claude doesn’t do anything stupid !  So, despite all of this being very obvious , it’s clear that the markets and an alarming number of people in the media simply do not know what they are talking about. The “AI replaces software” story is literally “Anthropic has released a product and now the resulting industry is selling off,” such as when it launched a cybersecurity tool that could check for vulnerabilities (a product that has existed in some form for nearly a decade) causing a sell-off in cybersecurity stocks like Crowdstrike — you know, the one that had a faulty bit of code cause a global cybersecurity incident that lost the Fortune 500 billions , and led to Delta Air Lines suspending over 1,200 flights over six long days of disruption .  There is no rational basis for anything about this sell-off other than that our financial media and markets do not appear to understand the very basic things about the stuff they invest in. Software may seem complex, but (especially in these cases) it’s really quite simple: investors are conflating “an AI model can spit out code” with “an AI model can create the entire experience of what we know as “software,” or is close enough that we have to start freaking out.” This is thanks to the intentionally-deceptive marketing pedalled by Anthropic and validated by the media. In a piece from September 2025, Bloomberg reported that Claude Sonnet 4.5 could “code on its own for up to 30 hours straight,”  a statement directly from Anthropic repeated by other outlets that added that it did so “on complex, multi-step tasks,” none of which were explained. The Verge, however, added that apparently Anthropic “ coded a chat app akin to Slack or Teams ,” and no, you can’t see it, or know anything about how much it costs or its functionality. Does it run? Is it useful? Does it work in any way? What does it look like? We have absolutely no proof this happened other than them saying it, but because the media repeated it it’s now a fact.  Perhaps it’s not a particularly novel statement, but it’s becoming kind of obvious that maybe the people with the money don’t actually know what they’re doing, which will eventually become a problem when they all invest in the wrong thing for the wrong reasons.   SaaS (Software as a Service, which almost always refers to business software) stocks became a hot commodity because they were perpetual growth machines with giant sales teams that existed only to make numbers go up, leading to a flurry of investment based on the assumption that all numbers will always increase forever, and every market is as giant as we want. Not profitable? No problem! You just had to show growth. It was easy to raise money because everybody saw a big, obvious path to liquidity, either from selling to a big firm or taking the company public… …in theory.  Per Victor Basta , between 2014 and 2017, the number of VC rounds in technology companies halved with a much smaller drop in funding, adding that a big part was the collapse of companies describing themselves as SaaS, which dropped by 40% in the same period. In a 2016 chat with VC David Yuan, Gainsight CEO Nick Mehta added that “the bar got higher and weights shifted in the public markets,” citing that profitability was now becoming more important to investors.  Per Mehta, one savior had arrived — Private Equity, with Thoma Bravo buying Blue Coat Systems in 2011 for $1.3 billion (which had been backed by a Canadian teacher’s pension fund!), Vista Equity buying Tibco for $4.3 billion in 2014, and Permira Advisers (along with the Canadian Pension Plan Investment Board) buying Informatica for $5.3 billion ( with participation from both Salesforce and Microsoft ) in 2015, 16 years after its first IPO. In each case, these firms were purchased using debt that immediately gets dumped onto the company’s balance sheet, known as a leveraged buyout.  In simple terms, you buy a company with money that the company you just bought has to pay off. The company in question also has to grow like gangbusters to keep up with both that debt and the private equity firm’s expectations. And instead of being an investor with a board seat who can yell at the CEO, it’s quite literally your company, and you can do whatever you want with (or to) it. Yuan added that the size of these deals made the acquisitions problematic, as did their debt-filled: Symantec would acquire Blue Coat for $4.65 billion in 2016 , for just under a 4x return. Things were a little worse for Tibco. Vista Equity Partners tried to sell it in 2021 amid a surge of other M&A transactions , with the solution — never change, private equity! — being to buy Citrix for $16.5 billion (a 30%% premium on its stock price) and merge it with Tibco, magically fixing the problem of “what do we do with Tibco?” by hiding it inside another transaction. Informatica eventually had a $10 billion IPO in 2021, which was flat in its first day of trading , never really did more than stay at its IPO price, then sold to Salesforce for $8 billion in 2025 , at an equity value of $8 billion , which seems fine but not great until you realize that, with inflation, the $5.3 billion that Permira invested in 2015 was about $7.15 billion in 2025’s money. In every case, the assumption was very simple: these businesses would grow and own their entire industries, the PE firm would be the reason they did this (by taking them private and filling them full of debt while making egregious growth demands), and the meteoric growth of SaaS would continue in perpetuity.  Yet the real year that broke things was 2021. As everybody returned to the real world, consumer and business spending skyrocketed, leading ( per Bloomberg ) to a massive surge in revenues that convinced private equity to shove even more cash and debt up the ass of SaaS: Bloomberg is a little nicer than I am, so they’re not just writing “deals were waved through because everybody assumed that software grows forever and nobody actually knew a thing about the technology or why it would grow so fast.” Unsurprisingly, this didn’t turn out to be true. Per The Information , PE firms invested in or bought 1,167 U.S. software companies for $202 billion, and usually hold investments for three to five years. Thankfully, they also included a chart to show how badly this went:  2021 was the year of overvaluation, and ( per Jason Lemkin of SaaStr ) 60% of unicorns (startups with $1bn+) valuations hadn’t raised funds in years. The massive accumulated overinvestment, combined with no obvious pathway to an exit, led to people calling these companies “ Zombie Unicorns ”: The problem, to quote The Information, is that “PE firms don’t want to lock in returns that are lower than what they promised their backers, say some executives at these firms,” and “many enterprise software firms’ revenue growth has slowed.” Per CNBC in November 2025 , private equity firms were facing the same zombie problem: Per Jason Lemkin , private equity is sitting on its largest collection of companies held for longer than four years since 2012, with McKinsey estimating that more than 16,000 companies (more than 52% of the total buyout-backed inventory) had been held by private equity for more than four years, the highest on record. In very simple terms, there are hundreds of billions of tech companies sitting in the wings of private equity firms that they’re desperate to sell, with the only customers being big tech firms, other private equity firms, and public offerings in one of the slowest IPO markets in history . Investing used to be easy. There were so many ideas for so many companies, companies that could be worth billions of dollars once they’d been fattened up with venture capital and/or private equity. There were tons of acquirers, it was easy to take them public, and all you really had to do was exist and provide capital. Companies didn’t have to be good , they just had to look good enough to sell. This created a venture capital and private equity industry based on symbolic value, and chased out anyone who thought too hard about whether these companies could actually survive on their own merits. Per PitchBook, since 2022, 70% of VC-backed exits were valued at less than the capital put in , with more than a third of them being startups buying other startups in 2024. Private equity firms are now holding assets for an average of 7 years , McKinsey also added one horrible detail for the overall private equity market, emphasis mine:  You see, private equity is fucking stupid, doesn’t understand technology, doesn’t understand business, and by setting up its holdings with debt based on the assumption of unrealistic growth, they’ve created a crisis for both software companies and the greater tech industry.  On February 6, more than $17.7 billion of US tech company loans dropped to “distressed” trading levels (as in trading as if traders don’t believe they’ll get paid, per Bloomberg ), growing the overall group of distressed tech loans to $46.9 billion, “dominated by firms in SaaS.” These firms included huge investments like Thoma Bravo’s Dayforce ( which it purchased two days before this story ran for $12.3 billion ) and Calabrio ( which it acquired for “over” $1 billion in April 2021 and merged with Verint in November 2025 ).  This isn’t just about the shit they’ve bought , but the destruction of the concept of “value” in the tech industry writ large. “Value” was not based on revenues, or your product, or anything other than your ability to grow and, ideally, trap as many customers as possible , with the vague sense that there would always be infinitely more money every year to spend on software.  Revenue growth came from massive sales teams compensated with heavy commissions and yearly price increases, except things have begun to sour, with renewals now taking twice as long to complete , and overall SaaS revenue growth slowing for years . To put it simply, much of the investment in software was based on the idea that software companies will always grow forever, and SaaS companies — which have “sticky” recurring revenues — would be the standard-bearer. When I got into the tech industry in 2008, I immediately became confused about the amount of unprofitable or unsustainable companies that were worth crazy amounts of money, and for the most part I’d get laughed at by reporters for being too cynical.  For the best part of 20 years, software startups have been seen as eternal growth-engines. All you had to do was find a product-market fit, get a few hundred customers locked in, up-sell them on new features and grow in perpetuity as you conquered a market. The idea was that you could just keep pumping them with cash, hire as many pre-sales (technical person who makes the sale), sales and customer experience (read: helpful person who also loves to tell you more stuff) people as you need to both retain customers and sell them as much stuff as you need.  Innovation was, as you’d expect, judged entirely by revenue growth and net revenue retention : In practice, this sounds reasonable: what percentage of your revenue are you making year-over-year? The problem is that this is a very easy to game stat, especially if you’re using it to raise money, because you can move customer billing periods around to make sure that things all continue to look good. Even then, per research by Jacco van der Kooji and Dave Boyce , net revenue retention is dropping quarter over quarter. The other problem is that the entire process of selling software has separated from the end-user, which means that products (and sales processes) are oriented around selling that software to the person responsible for buying it rather than those doomed to use it.  Per Nik Suresh’s Brainwash An Executive Today , in a conversation with the Chief Technology Officer of a company with over 10,000 people, who had asked if “data observability,” a thing that they did not (and would not need to, in their position) understand, was a problem, and whether Nik had heard of Monte Carlo. It turned out that the executive in question had no idea what Monte Carlo or data observability was , but because they’d heard about it on LinkedIn, it was now all they could think about.  This is the environment that private equity bought into — a seemingly-eternal growth engine with pliant customers desperate to spend money on a product that didn’t have to be good , just functional-enough. These people do not know what they are talking about or why they are buying these companies other than being able to mumble out shit like “ARR” and “NRR+” and “TAM” and “CAC” and “ARPA” in the right order to convince themselves that something is a good idea without ever thinking about what would happen if it wasn’t. This allowed them to stick to the “big picture,” meaning “numbers that I can look at rather than any practical experience in software development.” While I guess the concept of private equity isn’t morally repugnant, its current form — which includes venture capital — has led the modern state of technology into the fucking toilet, combining an initial flux of viable businesses, frothy markets and zero interest rates making it deceptively easy to raise money to acquire and deploy capital, leading to brainless investing, the death of logical due diligence, and potentially ruinous consequences for everybody involved. Private equity spent decades buying a little bit of just about everything, enriching the already-rich by engaging with the most vile elements of the Rot Economy’s growth-at-all-costs mindset . Its success is predicated on near-perpetual levels of liquidity and growth in both its holdings and the holdings of those who exist only to buy their stock, and on a tech and business media that doesn’t think too hard about the reality of the problems their companies claim to solve. The reckoning that’s coming is one built specifically to target the ignorant hubris that made them rich.  Private equity has yet to be punished by its limited partners and banks for investing in zombie assets, allowing it to pile into the unprofitable data centers underpinning the AI bubble, meaning that companies like Apollo, Blue Owl and Blackstone — all of whom participated in the ugly $10.2 billion acquisition of Zendesk in 2022 ( after it rejected another PE offer of $17 billion in 2021 ) that included $5 billion in debt — have all become heavily-leveraged in giant, ugly debt deals covering assets that are obsolete to useless in a few years . Alongside the fumbling ignorance of private equity sits the $3 trillion private credit industry , an equally-putrid, growth-drunk, and poorly-informed industry run with the same lax attention to detail and Big Brain Number Models that can justify just about any investment they want. Their half-assed due diligence led to billions of dollars of loans being given to outright frauds like First Brands , Tricolor and PosiGen , and, to paraphrase JP Morgan’s Jamie Dimon, there are absolutely more fraudulent cockroaches waiting to emerge . You may wonder why this matters, as all of this is private credit. Well, they get their money from banks. Big banks. In fact, according to the Federal Reserve of Boston , about 14% ($300 billion) of large banks’ total loan commitments to non-banking financial institutions in 2023 went to private equity and private credit, with Moody’s pegging the number around $285 billion, with an additional $340 billion in unused-yet-committed cash waiting in the wings . Oh, and they get their money from you . Pension funds are among some of the biggest backers of private credit companies , with the New York City Employees Retirement System and CalPERS increasing their investments.  Today, I’m going to teach you all about private equity, private credit, and why years of reframing “value” to mean “growth” may genuinely threaten the global banking system, as well as how effectively every company raises money. An entirely-different system exists for the wealthy to raise and deploy capital, one with flimsy due diligence, a genuine lack of basic industrial knowledge, and hundreds of billions of dollars of crap it can’t sell.  These people have been able to raise near-unlimited capital to do basically anything they want because there was always somebody stupid enough to buy whatever they were selling, and they have absolutely no plan for what happens when their system stops working.  They’ll loan to anyone or invest in anything that confirms their biases, and those biases are equal parts moronic and malevolent. Now they’re investing teachers’ pensions and insurance premiums in unprofitable and unsustainable data centers, all because they have no idea what a good investment actually looks like.  Welcome to the Hater’s Guide To Private Equity, or “The Stupidest Assholes In The Room.”

0 views
Jeff Geerling Yesterday

Upgrading my Open Source Pi Surveillance Server with Frigate

In 2024 I built a Pi Frigate NVR with Axzez's Interceptor 1U Case , and installed it in my 19" rack. Using a Coral TPU for object detection, it's been dutifully surveilling my property—on my terms (100% local, no cloud integration or account required). I've wanted to downsize the setup while keeping cheap large hard drives 1 , and an AI accelerator.

0 views
Kev Quirk Yesterday

Firefox AI Killswitch

Nice to see that the Firefox team have actually implemented their "AI killswitch" in the way that they said they would. Here's a screenshot from my copy of Firefox 148: Very happy to see this land, and it means I can end my hunt for a new browser for the time being. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
iDiallo Yesterday

We Need Process, But Process Gets in the Way

How do you manage a company with 50,000 employees? You need processes that give you visibility and control across every function such as technology, logistics, operations, and more. But the moment you try to create a single process to govern everyone, it stops working for anyone. One system can't cater to every team, every workflow, every context. When implemented you start seeing in-fighting, projects missing deadlines, people quitting. Compromises get made, and in my experience, it almost always becomes overwhelming. The first time I was part of a merger, I was naïve about how it would go. The narrative we were sold was reassuring. The larger company was acquiring us because we were successful. The last thing they'd want to do was get in the way of that success. But that's not how it went. It doesn't matter what made you successful before you join a larger organization. The principles and processes of the acquiring company are what will dominate. Your past success is acknowledged, maybe even celebrated, but it doesn't protect you from assimilation. One of the first things we had to adopt was Scrum. It may be standard practice now, but at the time it was still making its way through the industry. Our team, developers and product managers, already had a process that worked. We knew how to communicate, how to prioritize, how to ship. Adopting this new set of ceremonies felt counterproductive. It didn't make us faster. It didn't improve communication. What it did do was increase administrative overhead. Standups, sprints, retrospectives, layer after layer of structure added on top of work that was already getting done. But there was no going back. We were never going to return to being that nimble, ad hoc team that could resolve issues quickly and move on. We had to adopt methods that got in the way. Eventually, we adapted. We adopted the process. And in doing so, we became less efficient at the local level. A lot of people, frustrated by the slowdown, left for other opportunities. But as far as the larger company was concerned, that was acceptable. Our product was just one of many in their portfolio. Slowing down one team to get everyone aligned was a price they were willing to pay. It wasn't efficient, but it was manageable from their perspective. The math made sense at the organizational level, even if it felt like a loss from where we were standing. I understand that logic. I just don't think it's the best way forward. Think about how a computer works. A CPU doesn't concern itself with how a hard drive retrieves data. Whether it's spinning magnetic disks or a solid state drive, the internal mechanics are irrelevant to the CPU. All it knows is that it can make a request, and the response will come back in the expected format. If the CPU had to get involved in the actual process of fetching data, it would waste enormous processing power on something that isn't its concern. Organizations can work the same way. Rather than imposing a single process across every team, a company can treat its departments as independent components. You make a request, the department delivers an output. How they produce that output like what tools they use, how they run their meetings, how they structure their work, that shouldn't be a concern, as long as the result meets the requirement. There are places where unified processes make sense. Legal and compliance, for example, probably need to be consistent across the whole organization. But for how individual teams operate day to day, autonomy is often the better choice. Will every team's process be perfectly aligned with every other team's? No. But they'll actually work. And the people doing the work will be far less likely to walk out the door. Sometimes in large organizations, it's important to identify which process works, and which team is better left alone.

0 views

Dominik Schwind

This week on the People and Blogs series we have an interview with Dominik Schwind, whose blog can be found at lostfocus.de . Tired of RSS? Read this in your browser or sign up for the newsletter . People and Blogs is supported by the "One a Month" club members. If you enjoy P&B, consider becoming one for as little as 1 dollar a month. My name is Dominik Schwind and I'm from Lörrach , a small town on the German side of the tri-border area with Switzerland and France . I've been a web developer for a really long time now, mostly server-side and just occasionally dabbling in what is showing up in the browser. Annoyingly that's a hobby that I turned into work, so I guess that's ruined now. (Which doesn't stop me, though: I have too many half-finished side-project websites and apps to count.) Besides that I also really like to take photos and after a few years of being frozen in place I started to travel again, which is always nice. I do like watching motorsports of almost all types, I can easily get sucked into computer games like Factorio and I like to listen to podcasts, top of them being the Omnibus Project , Do Go On and Roderick on the Line . I've had a website since before I had internet access - some computer game I had in the mid-90s had the manual included as HTML and I used it to learn how to make basic websites. The very first day my father came home with a modem, I signed up for GeoCities and when I found a webhost that would allow me to run CGI scripts, I installed NewsPro , an early proto-blog system before blogging was even a thing. And while these early iterations of my website(s) are long gone, I haven't stopped since. The name came from an unease I started to feel in my final year of high school: once I finished school, I didn't know where to direct my energy and attention. That feeling hasn't really left since then. Mostly there is none - when I think of something that I want to communicate to someone, anyone , I try to put it online. Quite often it ends up on Mastodon but I do try to put things on my blog, especially when I know it is something future me would appreciate. A few years ago I noticed that I had neglecting my blog in favour of other ways of communicating and I started a pact with a couple of friends to write weeknotes . We're in our fourth year now, which feels like an accomplishment. I try to write those posts first thing on a Sunday morning, if possible. I write most of my posts in Markdown in iA Writer , which is probably the most arrogant Markdown editing app in the world. But I paid for it at some point, so I better use it, too. I basically only need a computer and a place to sit and I'm fine. I've tried to find ways to blog from my phone but in the end, I prefer a proper keyboard and a bigger screen. While I never observed any difference in blogging creativity depending on the physical space, I actually quite enjoy writing in places other than my desk. This one is actually pretty simple: I run WordPress , currently on a DigitalOcean VM. One of the points on my long to-do list for my web stuff is to move it to Hetzner , which probably would only take an evening. And yet, I procrastinate. I've (more or less) jokingly said I'd replace WordPress with a CMS of my own making for years now, but at some point I've resigned, even though my database is a mess. Probably not. Ever since the beginning I wrote for two audiences: my friends and future me. I'm really happy when someone else finds my blog and might turn into an internet friend, but I wouldn't know how else to achieve that other than what I've been doing for all these years now. .de domains are pretty affordable, so it is that plus the server, which is around €100 per year. The blog doesn't generate any revenue, in many ways it's "only" a journal. When it comes to other bloggers, I'd say: go for it if you think your writing (or your photography or whatever it might be you're sharing on your website) is something that can be turned into revenue, one way or another. In many ways I'm a bit bummed that Flattr (or something similar) never really took of, I would happily use a service like that. Of course I need to mention my friends and fellow weeknoters: Martin (blogs in German) and Teymur . (NSFW) Three of the people whose blogs I read have been interviewed here already: Ahn ( Interview ), Jeremy Keith ( Interview ) and Winnie Lim .( Interview ) Some other people whose blogs I read and who might be interesting people to answer your questions would be Jennifer Mills , (who has the best take on weekly blog posts I have ever seen) Nikkin , (he calls it a newsletter, but there is an RSS feed) Roy Tang and Ruben Schade . If you don't have one yet, go start a personal website! Don't take it too seriously, try things and it can be a nice, meditative hobby and helps against the urge to doomscroll. Also you might never know, your kind of people might find it and connect with you. Now that you're done reading the interview, go check the blog and subscribe to the RSS feed . If you're looking for more content, go read one of the previous 130 interviews . People and Blogs is possible because kind people support it.

0 views
ava's blog Yesterday

[photo dump] recent few weeks

Another photo dump is due. I saw a funny and unconventional ring online and I had to have it. Sorry, I love it so much. I already lost the white paper in it because it is just glued on, but I like it even more without it. Moving on to food... My wife made sushi. She also made matcha strawberry cookies: We're also on a bread baking journey because bread prices are ridiculous now. Our first few attempts were a fail, but now we have some awesome breads and it keeps getting better and better. One time, our sourdough starter escaped containment: It was also Valentine's day and the anniversary of my wife and I. Some chocolates, chocolate pancakes in bed, and flowers. We also played some Commander in the LGS. And I tidied up my wardrobe, and accidentally melted a container top on the toaster: Reply via email Published 27 Feb, 2026

0 views
David Bushell Yesterday

Croissant and CORS proxy update

Croissant is my home-cooked RSS reader. I wish it was only a progressive web app (PWA) but due to missing CORS headers, many feeds remain inaccessible. My RSS feeds have the header and so should yours! Blogs Are Back has a guide to enable CORS for your blog . Bypassing CORS requires some kind of proxy. Other readers use a custom browser extension. That is clever, but extensions can be dangerous. I decided on two solutions. I wrapped my PWA in a Tauri app . This is also dangerous if you don’t trust me. I also provided a server proxy for the PWA. A proxy has privacy concerns but is much safer. I’m sorry if anyone is using Croissant as a PWA because the proxy is now gone. If a feed has the correct CORS headers it will continue to work. Sorry for the abrupt change. That’s super lame, I know! To be honest I’ve lost a bit of enthusiasm for the project and I can’t maintain a proxy. Croissant was designed to be limited in scope to avoid too much burden. In hindsight the proxy was too ambitious. Technically, yes! But you’ll have to figure that out by yourself. If you have questions, such as where to find the code, how the code works etc, the answer is no. I don’t mean to be rude, I just don’t have any time! You’re welcome to ask for support but unless I can answer in 30 seconds I’ll have to decline. Croissant is feature complete! It does what I set out to achieve. I have fixed several minor bugs and tweaked a few styles. Until inspiration (or a bug) strikes I won’t do another update anytime soon. Maybe later in the year I’ll decide to overhaul it? Who can predict! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
Kev Quirk Yesterday

Quick Clarification on Pure Comments

A couple of people have reached out to me asking if I can offer a version of Pure Comments for their site, as they don't run Pure Blog . I obviously didn't make this clear in the announcement , or on the (now updated) Pure Comments site. Pure Comments can be used on ANY website. It's just an embed script, just like Disqus (only with no bloat or tracking). So you just have to upload the files to wherever you want to host Pure Comments, then add the following embed code wherever you want comments to display (replacing the example domain): You can use Pure Comments on WordPress, Bear Blog, Jekyll, 11ty, Hugo, Micro.blog, Kirby, Grav, and even Pure Blog! Anywhere you can inject the little snippet of code above, Pure Comments will work. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
(think) Yesterday

Building Emacs Major Modes with TreeSitter: Lessons Learned

Over the past year I’ve been spending a lot of time building TreeSitter-powered major modes for Emacs – clojure-ts-mode (as co-maintainer), neocaml (from scratch), and asciidoc-mode (also from scratch). Between the three projects I’ve accumulated enough battle scars to write about the experience. This post distills the key lessons for anyone thinking about writing a TreeSitter-based major mode, or curious about what it’s actually like. Before TreeSitter, Emacs font-locking was done with regular expressions and indentation was handled by ad-hoc engines (SMIE, custom indent functions, or pure regex heuristics). This works, but it has well-known problems: Regex-based font-locking is fragile. Regexes can’t parse nested structures, so they either under-match (missing valid code) or over-match (highlighting inside strings and comments). Every edge case is another regex, and the patterns become increasingly unreadable over time. Indentation engines are complex. SMIE (the generic indentation engine for non-TreeSitter modes) requires defining operator precedence grammars for the language, which is hard to get right. Custom indentation functions tend to grow into large, brittle state machines. Tuareg’s indentation code, for example, is thousands of lines long. TreeSitter changes the game because you get a full, incremental, error-tolerant syntax tree for free. Font-locking becomes “match this AST pattern, apply this face”: And indentation becomes “if the parent node is X, indent by Y”: The rules are declarative, composable, and much easier to reason about than regex chains. In practice, ’s entire font-lock and indentation logic fits in about 350 lines of Elisp. The equivalent in tuareg is spread across thousands of lines. That’s the real selling point: simpler, more maintainable code that handles more edge cases correctly . That said, TreeSitter in Emacs is not a silver bullet. Here’s what I ran into. TreeSitter grammars are written by different authors with different philosophies. The tree-sitter-ocaml grammar provides a rich, detailed AST with named fields. The tree-sitter-clojure grammar, by contrast, deliberately keeps things minimal – it only models syntax, not semantics, because Clojure’s macro system makes static semantic analysis unreliable. 1 This means font-locking forms in Clojure requires predicate matching on symbol text, while in OCaml you can directly match nodes with named fields. To illustrate: here’s how you’d fontify a function definition in OCaml, where the grammar gives you rich named fields: And here’s the equivalent in Clojure, where the grammar only gives you lists of symbols and you need predicate matching: You can’t learn “how to write TreeSitter queries” generically – you need to learn each grammar individually. The best tool for this is (to visualize the full parse tree) and (to see the node at point). Use them constantly. You’re dependent on someone else providing the grammar, and quality is all over the map. The OCaml grammar is mature and well-maintained – it’s hosted under the official tree-sitter GitHub org. The Clojure grammar is small and stable by design. But not every language is so lucky. asciidoc-mode uses a third-party AsciiDoc grammar that employs a dual-parser architecture – one parser for block-level structure (headings, lists, code blocks) and another for inline formatting (bold, italic, links). This is the same approach used by Emacs’s built-in , and it makes sense for markup languages where block and inline syntax are largely independent. The problem is that the two parsers run independently on the same text, and they can disagree . The inline parser misinterprets and list markers as emphasis delimiters, creating spurious bold spans that swallow subsequent inline content. The workaround is to use on all block-level font-lock rules so they win over the incorrect inline faces: This doesn’t fix inline elements consumed by the spurious emphasis – that requires an upstream grammar fix. When you hit grammar-level issues like this, you either fix them yourself (which means diving into the grammar’s JavaScript source and C toolchain) or you live with workarounds. Either way, it’s a reminder that your mode is only as good as the grammar underneath it. Getting the font-locking right in was probably the most challenging part of all three projects, precisely because of these grammar quirks. I also ran into a subtle behavior: the default font-lock mode ( ) skips an entire captured range if any position within it already has a face. So if you capture a parent node like and a child was already fontified, the whole thing gets skipped silently. The fix is to capture specific child nodes instead: These issues took a lot of trial and error to diagnose. The lesson: budget extra time for font-locking when working with less mature grammars . Grammars evolve, and breaking changes happen. switched from the stable grammar to the experimental branch because the stable version had metadata nodes as children of other nodes, which caused and to behave incorrectly. The experimental grammar makes metadata standalone nodes, fixing the navigation issues but requiring all queries to be updated. pins to v0.24.0 of the OCaml grammar. If you don’t pin versions, a grammar update can silently break your font-locking or indentation. The takeaway: always pin your grammar version , and include a mechanism to detect outdated grammars. tests a query that changed between versions to detect incompatible grammars at startup. Users shouldn’t have to manually clone repos and compile C code to use your mode. Both and include grammar recipes: On first use, the mode checks and offers to install missing grammars via . This works, but requires a C compiler and Git on the user’s machine, which is not ideal. 2 The TreeSitter support in Emacs has been improving steadily, but each version has its quirks: Emacs 29 introduced TreeSitter support but lacked several APIs. For instance, (used for structured navigation) doesn’t exist – you need a fallback: Emacs 30 added , sentence navigation, and better indentation support. But it also had a bug in offsets ( #77848 ) that broke embedded parsers, and another in that required to disable its TreeSitter-aware version. Emacs 31 has a bug in where an off-by-one error causes to leave ` *)` behind on multi-line OCaml comments. I had to skip the affected test with a version check: The lesson: test your mode against multiple Emacs versions , and be prepared to write version-specific workarounds. CI that runs against Emacs 29, 30, and snapshot is essential. Most TreeSitter grammars ship with query files for syntax highlighting ( ) and indentation ( ). Editors like Neovim and Helix use these directly. Emacs doesn’t – you have to manually translate the patterns into and calls in Elisp. This is tedious and error-prone. For example, here’s a rule from the OCaml grammar’s : And here’s the Elisp equivalent you’d write for Emacs: The query syntax is nearly identical, but you have to wrap everything in calls, map upstream capture names ( ) to Emacs face names ( ), assign features, and manage behavior. You end up maintaining a parallel set of queries that can drift from upstream. Emacs 31 will introduce which will make it possible to use files for font-locking, which should help significantly. But for now, you’re hand-coding everything. When a face isn’t being applied where you expect: TreeSitter modes define four levels of font-locking via , and the default level in Emacs is 3. It’s tempting to pile everything into levels 1–3 so users see maximum highlighting out of the box, but resist the urge. When every token on the screen has a different color, code starts looking like a Christmas tree and the important things – keywords, definitions, types – stop standing out. Less is more here. Here’s how distributes features across levels: And follows the same philosophy: The pattern is the same: essentials first, progressively more detail at higher levels. This way the default experience (level 3) is clean and readable, and users who want the full rainbow can bump to 4. Better yet, they can use to cherry-pick individual features regardless of level: This gives users fine-grained control without requiring mode authors to anticipate every preference. Indentation issues are harder to diagnose because they depend on tree structure, rule ordering, and anchor resolution: Remember that rule order matters for indentation too – the first matching rule wins. A typical set of rules reads top to bottom from most specific to most general: Watch out for the empty-line problem : when the cursor is on a blank line, TreeSitter has no node at point. The indentation engine falls back to the root node as the parent, which typically matches the top-level rule and gives column 0. In neocaml I solved this with a rule that looks at the previous line’s last token to decide indentation: This is the single most important piece of advice. Font-lock and indentation are easy to break accidentally, and manual testing doesn’t scale. Both projects use Buttercup (a BDD testing framework for Emacs) with custom test macros. Font-lock tests insert code into a buffer, run , and assert that specific character ranges have the expected face: Indentation tests insert code, run , and assert the result matches the expected indentation: Integration tests load real source files and verify that both font-locking and indentation survive on the full file. This catches interactions between rules that unit tests miss. has 200+ automated tests and has even more. Investing in test infrastructure early pays off enormously – I can refactor indentation rules with confidence because the suite catches regressions immediately. When I became the maintainer of clojure-mode many years ago, I really struggled with making changes. There were no font-lock or indentation tests, so every change was a leap of faith – you’d fix one thing and break three others without knowing until someone filed a bug report. I spent years working on a testing approach I was happy with, alongside many great contributors, and the return on investment was massive. The same approach – almost the same test macros – carried over directly to when we built the TreeSitter version. And later I reused the pattern again in and . One investment in testing infrastructure, four projects benefiting from it. I know that automated tests, for whatever reason, never gained much traction in the Emacs community. Many popular packages have no tests at all. I hope stories like this convince you that investing in tests is really important and pays off – not just for the project where you write them, but for every project you build after. This one is specific to but applies broadly: compiling TreeSitter queries at runtime is expensive. If you’re building queries dynamically (e.g. with called at mode init time), consider pre-compiling them as values. This made a noticeable difference in ’s startup time. The Emacs community has settled on a suffix convention for TreeSitter-based modes: , , , and so on. This makes sense when both a legacy mode and a TreeSitter mode coexist in Emacs core – users need to choose between them. But I think the convention is being applied too broadly, and I’m afraid the resulting name fragmentation will haunt the community for years. For new packages that don’t have a legacy counterpart, the suffix is unnecessary. I named my packages (not ) and (not ) because there was no prior or to disambiguate from. The infix is an implementation detail that shouldn’t leak into the user-facing name. Will we rename everything again when TreeSitter becomes the default and the non-TS variants are removed? Be bolder with naming. If you’re building something new, give it a name that makes sense on its own merits, not one that encodes the parsing technology in the package name. I think the full transition to TreeSitter in the Emacs community will take 3–5 years, optimistically. There are hundreds of major modes out there, many maintained by a single person in their spare time. Converting a mode from regex to TreeSitter isn’t just a mechanical translation – you need to understand the grammar, rewrite font-lock and indentation rules, handle version compatibility, and build a new test suite. That’s a lot of work. Interestingly, this might be one area where agentic coding tools can genuinely help. The structure of TreeSitter-based major modes is fairly uniform: grammar recipes, font-lock rules, indentation rules, navigation settings, imenu. If you give an AI agent a grammar and a reference to a high-quality mode like , it could probably scaffold a reasonable new mode fairly quickly. The hard parts – debugging grammar quirks, handling edge cases, getting indentation just right – would still need human attention, but the boilerplate could be automated. Still, knowing the Emacs community, I wouldn’t be surprised if a full migration never actually completes. Many old-school modes work perfectly fine, their maintainers have no interest in TreeSitter, and “if it ain’t broke, don’t fix it” is a powerful force. And that’s okay – diversity of approaches is part of what makes Emacs Emacs. TreeSitter is genuinely great for building Emacs major modes. The code is simpler, the results are more accurate, and incremental parsing means everything stays fast even on large files. I wouldn’t go back to regex-based font-locking willingly. But it’s not magical. Grammars are inconsistent across languages, the Emacs APIs are still maturing, you can’t reuse files (yet), and you’ll hit version-specific bugs that require tedious workarounds. The testing story is better than with regex modes – tree structures are more predictable than regex matches – but you still need a solid test suite to avoid regressions. If you’re thinking about writing a TreeSitter-based major mode, do it. The ecosystem needs more of them, and the experience of working with syntax trees instead of regexes is genuinely enjoyable. Just go in with realistic expectations, pin your grammar versions, test against multiple Emacs releases, and build your test suite early. Anyways, I wish there was an article like this one when I was starting out with and , so there you have it. I hope that the lessons I’ve learned along the way will help build better modes with TreeSitter down the road. That’s all I have for you today. Keep hacking! See the excellent scope discussion in the tree-sitter-clojure repo for the rationale.  ↩︎ There’s ongoing discussion in the Emacs community about distributing pre-compiled grammar binaries, but nothing concrete yet.  ↩︎ Regex-based font-locking is fragile. Regexes can’t parse nested structures, so they either under-match (missing valid code) or over-match (highlighting inside strings and comments). Every edge case is another regex, and the patterns become increasingly unreadable over time. Indentation engines are complex. SMIE (the generic indentation engine for non-TreeSitter modes) requires defining operator precedence grammars for the language, which is hard to get right. Custom indentation functions tend to grow into large, brittle state machines. Tuareg’s indentation code, for example, is thousands of lines long. Use to verify the node type at point matches your query. Set to to see which rules are firing. Check the font-lock feature level – your rule might be in level 4 while the user has the default level 3. The features are assigned to levels via . Remember that rule order matters . Without , an earlier rule that already fontified a region will prevent later rules from applying. This can be intentional (e.g. builtin types at level 3 take precedence over generic types) or a source of bugs. Set to – this logs which rule matched for each line, what anchor was computed, and the final column. Use to understand the parent chain. The key question is always: “what is the parent node, and which rule matches it?” Remember that rule order matters for indentation too – the first matching rule wins. A typical set of rules reads top to bottom from most specific to most general: Watch out for the empty-line problem : when the cursor is on a blank line, TreeSitter has no node at point. The indentation engine falls back to the root node as the parent, which typically matches the top-level rule and gives column 0. In neocaml I solved this with a rule that looks at the previous line’s last token to decide indentation: See the excellent scope discussion in the tree-sitter-clojure repo for the rationale.  ↩︎ There’s ongoing discussion in the Emacs community about distributing pre-compiled grammar binaries, but nothing concrete yet.  ↩︎

0 views
Rik Huijzer Yesterday

How To Run Services on a Linux Server

I have been running services myself for a few years on Linux servers. It took a while to figure out what works best. Here's what I've learned. First of all, all maintenance is done on headless servers via SSH. Learning this might seem daunting for some at first, but it is truly unbeatable in terms of productivity and speed. To easily log in via SSH, add the SSH keys to the server and then add the server to your `~/.ssh/config`. For example, ``` Host arnold Hostname 123.456.789.012 User rik IdentityFile ~/.ssh/arnold ``` Now you can log in via `ssh arnold` instead of having to ma...

0 views

I made a voice note taker

Have you ever always wanted a very very small voice note recorder that would fit in your pocket? Something that would always work, and always be available to take a note at the touch of a button, with no fuss? Me neither. Until, that is, I saw the Pebble Index 01 , then I absolutely needed it right away and had to have it in my life immediately, but alas, it is not available, plus it’s disposable, and I don’t like creating e-waste. What was a poor maker like me supposed to do when struck down so cruelly by the vicissitudes of fate? There was only one thing I could do: I could build my own, shitty version of it for $8, and that’s exactly what I did. Like everyone else, I have some sort of undiagnosed ADHD, which manifests itself as my brain itching for a specific task, and the itch becoming unbearable unless I scratch it. This usually results in me getting my phone out, no matter where I am or who I’m with, and either noting stuff down or doing the task, which some people perceive as rude, for inexplicable reasons that are almost certainly their fault. Because, however, it has proved easier to just not get my phone out in polite company than convince everyone of how wrong they are, I just do the former now, but that makes the itch remain. Also, sometimes I’m just in the middle of something, and an idea pops into my head for later pursuit, but I get distracted by a squirrel, a car going by, or the disturbing trend of the constant and persistent erosion of civil rights all over the world, and I forget the idea. The Pebble Index showed me that there’s a better way, a device that’s unobtrusive, available, and reliable enough that I could just press a button, speak into it, and know for sure that my sonorous voice would reach the bowels of my phone, where it would be stored safely until I was bored and wanted something to do. I didn’t want to have to get my phone out, unlock it, open a voice recorder app, hold down a button, speak, wonder if it heard me, look at the button, realize I had already pressed it, press it again, say the thing again, press it again to stop, exit the app, lock my phone, and put it back into my pocket. I wanted to take a thing out, press a button, speak, release the button, done. The initial thinking was that I’d use a microcontroller (an ESP32 is my microcontroller of choice these days), a microphone, and a lithium battery, and that’s basically all the hardware this needs! Most of the heavy lifting would need to be done in software. This would need: Luckily, I know enough about electronics to know that LLMs would definitely know how to build something like that. Indeed, Claude confirmed my suspicions by saying that all I need is a microphone and an ESP32. It recommended an ESP32-C6 but I went with an ESP32-S3 , as it had an onboard charge controller and would be able to charge a lithium battery from USB, which is very handy when you’re making a thing that runs on battery. The ESP32 is a microcontroller, a little computer that’s just really small. The main difference of the S3 from the C6 is that the S3 is more capable, and has more power. I keep an assortment of random components around, so I had an ESP32-S3 board. It’s a no-name, crappy one from AliExpress, not a good, Seeed-branded one from AliExpress, but it would have to do. Unfortunately, I didn’t have a MEMS microphone (which is basically an angelic grain of rice that can hear, with excellent quality), but I did have an electret mic, which is huge and bad quality and would sound like an old-timey radio, but it was there and it was ready and it was willing, and after a few beers it seemed like it was right, or at least right for right now. I also had a very thin LiPo battery, which would suit very well. For the final device I’d want a battery that’s a tiny bit shorter, as this one was around 40% longer than the ESP32, but it would do great for now. I quickly soldered everything together and recorded some audio. It worked! It worked and nobody was going to take that from me, even though it was crackly and the quality wasn’t great. Unfortunately, at this stage I realized that the analog electret microphone consumes too much energy, even when sleeping, which is terrible on a device that would spend more time sleeping than the beauty from that fairytale, Sleepy the Dwarf. To counteract that, I decided to use a MOSFET to cut power to the mic when the device was asleep. A MOSFET is a little switch that you can turn on and off from a microcontroller, basically. Full disclosure here, before using the MOSFET to turn the mic on and off, I went down a multi-hour rabbit hole trying to design a latching circuit that would allow the ESP32 to turn itself off and consume almost no power. Instead, it consumed a lot of my time, without anything to show for it, because I didn’t manage to make it work at all. The MOSFET for the mic worked fairly well, though, and the device didn’t consume much power when asleep. The real gains, however, were going to be had when the MEMS microphone I ordered arrived, as those use infinitesimal amounts of current when asleep, and have much better sound quality as well, as they are digital. The analog microphone crackled and popped and took a while to stabilize after boot, which was unfortunate because I wanted the device to be ready as soon as the user pressed the button. There was also a recording bug where the recording was missing a few milliseconds of audio every so often, which led to dropped phonemes and words sometimes sounding like other words because parts of them were dropped. All these problems were weird enough and hard enough to debug that I resolved to just wait for my digital MEMS microphone to arrive, which would solve them in one fell swoop, as it is digital and amazing. After the relatively easy part of connecting a few wires together, now came the hard part: Designing a case for the whole thing that would fit without leaving much empty space, to make the device as small as possible. This was very hard to do with this massive microphone that was as tall as everything else (including battery) combined. I initially tried to point the microphone downward while mounting it at the top, so it would take up the least amount of vertical space possible, but the PCB made that hard, as the microphone was soldered to it. I ended up desoldering the mic from the PCB, trimming the PCB to make it shorter, and connecting the mic to it with wires. That allowed me to make the case (and thus the device) smaller, but at what cost? Nothing, turns out, because it worked great. The device was working great, but I didn’t want it tethered to my computer, I wanted to be able to take it out and about and show it the wonders of the world. To do this, I needed Bluetooth. Unfortunately, I have exactly zero idea how Bluetooth works, and would need to spend days or weeks figuring stuff out, but, luckily for me, I had a Claude subscription. It took a bit of back-and-forth, but I did manage to end up with a Python script that would connect to the pendant, download the audio files, and convert them from ADPCM to MP3, for expanded compatibility. To maximize battery life, the way things worked was: This worked really well, the device was awake for a small amount of time (10 seconds), but it could be awoken at any time just by tapping the button. At that point, it would transfer to the PC any files that were on the pendant, and go back to sleep. One downside was that transfers would take an inordinate amount of time, sometimes reaching 2 minutes for a 10-second clip. OpenAI’s Codex was really helpful here, finding a solution for fast BLE transfers that made sending files 100x faster than it was before. Because I’m too impatient to wait for the slow boat from China, I ordered the same microphone locally. I had to pay an arm and a leg in shipping and impatience fees, but it was worth it, because I finally had a MEMS mic! It’s so cute and tiny, I immediately found a spot for it over the board, added the switch, added a voltage divider for sensing battery voltage, and that was it! The new mic sounds fantastic, it sounds better than recording with your phone, for some odd reason that I’m sure is all in my head. What’s more, it doesn’t have the weird bugs that plagued me with the analog mic. With this smaller mic, I could now design a better case. I designed the case you see on the right, which is the second generation. There will be a third, when I receive the shorter battery, which means I will have a choice of either making the device longer but half as thick, or around 40% shorter. I think I will go for longer but thinner, I’d quite prefer to have a thin device in my pocket, even if it’s long, than a stubby one that pokes out. Still, the new battery (and the new case) will mark the completion of this project and make me a very happy man. For the second-gen case, I decided to jazz it up and add a red stripe around it, because it was easy to do and because I think it looks good. Unfortunately, the feature I wanted most (fillets, i.e. rounded corners) wasn’t possible due to the lack of empty space inside the case. I hope the final device will have some more space for fillets, at least. Once I was done with the device, it was time to make it more ergonomic: I’d need to create an Android app so I wouldn’t have to wait to get to my PC. I also knew I wanted note transcription, as it’s really useful to be able to see what you said without having to listen to the audio again. Unfortunately again, I have no idea about Android development, only having written a small app years ago. Fortunately, though, Claude turned out to be pretty good at it, and one-shotted this app that you see here. For the transcription, I used GPT-4o Transcribe, which is great and understands both English and Greek, languages I fail to speak in equal measure. I have to say, it’s pretty magical to speak into a little box and to see the audio already captured and transcribed on your phone. With the Android app, I could now test the device in real-world use. One thing I noticed is that battery dies way too fast. I suspect that has something to do with the cheap board, so I’ve ordered an original Seeed Xiao board, and I hope that will fix the problem once and for all, as they advertise low power usage and they’re a trustworthy brand. I also added a “webhook” convenience function to the Android app, so that the latter would be able to send the transcription to a server for further processing. The device is extremely reliable, which makes me a lot more likely to use it. I know that, if I press the button, the audio will be recorded and stored, and nothing will happen to it, which makes for a very relaxed and calming experience. Before I continue, I want to say you can find all the files in this project (firmware, Android app, whatever else) in its GitHub repository: https://github.com/skorokithakis/middle That’s right, I called it Middle, because it was the next thing after the Index. I know it’s a silly name, I don’t care, don’t use it, I’m not changing it. In the “draw the rest of the fucking owl” portion of this article, I realized I didn’t want the notes to just go to my phone when LLMs exist. I wanted an LLM to take the notes and do something with them, so I spent a few weeks writing an AI agent that’s more useful than what currently exists. The device’s Android app sends the transcribed text to this AI, which processes it. I’m going to write another post about this, but basically, I wanted an AI personal assistant that could help with all the little chores in my life. AI assistants are interesting because they’re: This means that, when everyone inevitably asks “what is it good for”, I can’t really give a good answer, because the answer is “it takes care of all the little annoyances for me”, but nobody has the same annoyances and can’t really imagine what the bot does, so they don’t engage with it. The amazing thing for AI assistants for me is the fact that they can string together multiple (otherwise small) tools to do something that’s more valuable than the sum of its parts. For example, I asked the agent to give me a daily briefing every morning, consisting of my todos for the day, my calendar events, whether any refund has hit my bank, and whether any packages are due to be delivered today. The agent also checks my gym bookings and asks me every morning if I do plan to go, or if I intend to cancel. If I tell it to cancel, it does, but if I say I’ll go, it sets an alarm for a few minutes before, which I’m much more likely to see than my calendar’s one. It will also (entirely of its own volition) mention things like “you have a gym booking today 7-8pm but you have a restaurant booking at 9pm and it’ll take you more than an hour to shower and make it”, which a regular calendar wouldn’t be able to figure out. I’ve made it fantastically secure, everything is sandboxed and you can run it on your laptop without fear. I use it constantly throughout the day for many little things, and the integration with the device takes the whole setup to another level. You can find the bot here: https://github.com/skorokithakis/stavrobot Do let me know if you try it, it’s like OpenClaw but won’t steal your data and eat your firstborn. If you have any ideas, feedback, flamebait, or whatever, you can Tweet or Bluesky me, or email me directly. A way for the device to record audio onto some sort of persistent storage, for the case where you didn’t have your phone close to you. A way for the device to sleep, consuming almost no power, until it was woken up by the button. A way to transfer the files from the device to the phone, for later listening. A battery indicator would be very nice, so I knew when to recharge it. You pressed the button. If you held it down for more than half a second, the recording would “count”. If there was a recording made (i.e. if you held the button down long enough), it would be saved. Bluetooth would turn on and look for a phone or computer that’s ready to receive. The device would send the file and go to sleep again. Very open-ended tools, and Highly personal.

0 views
baby steps Yesterday

How Dada enables internal references

In my previous Dada blog post, I talked about how Dada enables composable sharing. Today I’m going to start diving into Dada’s permission system; permissions are Dada’s equivalent to Rust’s borrow checker. Dada aims to exceed Rust’s capabilities by using place-based permissions. Dada lets you write functions and types that capture both a value and things borrowed from that value . As a fun example, imagine you are writing some Rust code to process a comma-separated list, just looking for entries of length 5 or more: One of the cool things about Rust is how this code looks a lot like some high-level language like Python or JavaScript, but in those languages the call is going to be doing a lot of work, since it will have to allocate tons of small strings, copying out the data. But in Rust the values are just pointers into the original string and so is very cheap. I love this. On the other hand, suppose you want to package up some of those values, along with the backing string, and send them to another thread to be processed. You might think you can just make a struct like so… …and then create the list and items and store them into it: But as experienced Rustaceans know, this will not work. When you have borrowed data like an , that data cannot be moved. If you want to handle a case like this, you need to convert from into sending indices, owned strings, or some other solution. Argh! Dada does things a bit differently. The first thing is that, when you create a reference, the resulting type names the place that the data was borrowed from , not the lifetime of the reference . So the type annotation for would say 1 (at least, if you wanted to write out the full details rather than leaving it to the type inferencer): I’ve blogged before about how I would like to redefine lifetimes in Rust to be places as I feel that a type like is much easier to teach and explain: instead of having to explain that a lifetime references some part of the code, or what have you, you can say that “this is a that references the variable ”. But what’s also cool is that named places open the door to more flexible borrows. In Dada, if you wanted to package up the list and the items, you could build a type like so: Note that last line – . We can create a new class and move into it along with , which borrows from list. Neat, right? OK, so let’s back up and talk about how this all works. Let’s start with syntax. Before we tackle the example, I want to go back to the example from previous posts, because it’s a bit easier for explanatory purposes. Here is some Rust code that declares a struct , creates an owned copy of it, and then gets a few references into it. The Dada equivalent to this code is as follows: The first thing to note is that, in Dada, the default when you name a variable or a place is to create a reference. So doesn’t move , as it would in Rust, it creates a reference to the stored in . You could also explicitly write , but that is not preferred. Similarly, creates a reference to the value in the field . (If you wanted to move the character, you would write , not as in Rust.) Notice that I said “creates a reference to the stored in ”. In particular, I did not say “creates a reference to ”. That’s a subtle choice of wording, but it has big implications. The reason I wrote that “creates a reference to the stored in ” and not “creates a reference to ” is because, in Dada, references are not pointers . Rather, they are shallow copies of the value, very much like how we saw in the previous post that a acts like an but is represented as a shallow copy. So where in Rust the following code… …looks like this in memory… in Dada, code like this would look like so Clearly, the Dada representation takes up more memory on the stack. But note that it doesn’t duplicate the memory in the heap, which tends to be where the vast majority of the data is found. This gets at something important. Rust, like C, makes pointers first-class. So given , refers to the pointer and refers to its referent, the . Dada, like Java, goes another way. is a value – including in memory representation! The difference between a , , and is not in their memory layout, all of them are the same, but they differ in whether they own their contents . 2 So in Dada, there is no operation to go from “pointer” to “referent”. That doesn’t make sense. Your variable always contains a string, but the permissions you have to use that string will change. In fact, the goal is that people don’t have to learn the memory representation as they learn Dada, you are supposed to be able to think of Dada variables as if they were all objects on the heap, just like in Java or Python, even though in fact they are stored on the stack. 3 In Rust, you cannot move values while they are borrowed. So if you have code like this that moves into … …then this code only compiles if is not used again: There are two reasons that Rust forbids moves of borrowed data: Neither of these apply to Dada: OK, let’s revisit that Rust example that was giving us an error. When we convert it to Dada, we find that it type checks just fine: Woah, neat! We can see that when we move from into , the compiler updates the types of the variables around it. So actually the type of changes to . And then when we move from to , that’s totally valid. In PL land, updating the type of a variable from one thing to another is called a “strong update”. Obviously things can get a bit complicated when control-flow is involved, e.g., in a situation like this: OK, let’s take the next step. Let’s define a Dada function that takes an owned value and another value borrowed from it, like the name, and then call it: We could call this function like so, as you might expect: So…how does this work? Internally, the type checker type-checks a function call by creating a simpler snippet of code, essentially, and then type-checking that . It’s like desugaring but only at type-check time. In this simpler snippet, there are a series of statements to create temporary variables for each argument. These temporaries always have an explicit type taken from the method signature, and they are initialized with the values of each argument: If this type checks, then the type checker knows you have supplied values of the required types, and so this is a valid call. Of course there are a few more steps, but that’s the basic idea. Notice what happens if you supply data borrowed from the wrong place: This will fail to type check because you get: So now, if we go all the way back to our original example, we can see how the example worked: Basically, when you construct a , that’s “just another function call” from the type system’s perspective, except that in the signature is handled carefully. I should be clear, this system is modeled in the dada-model repository, which implements a kind of “mini Dada” that captures what I believe to be the most interesting bits. I’m working on fleshing out that model a bit more, but it’s got most of what I showed you here. 5 For example, here is a test that you get an error when you give a reference to the wrong value. The “real implementation” is lagging quite a bit, and doesn’t really handle the interesting bits yet. Scaling it up from model to real implementation involves solving type inference and some other thorny challenges, and I haven’t gotten there yet – though I have some pretty interesting experiments going on there too, in terms of the compiler architecture. 6 I believe we could apply most of this system to Rust. Obviously we’d have to rework the borrow checker to be based on places, but that’s the straight-forward part. The harder bit is the fact that is a pointer in Rust, and that we cannot readily change. However, for many use cases of self-references, this isn’t as important as it sounds. Often, the data you wish to reference is living in the heap, and so the pointer isn’t actually invalidated when the original value is moved. Consider our opening example. You might imagine Rust allowing something like this in Rust: In this case, the data is heap-allocated, so moving the string doesn’t actually invalidate the value (it would invalidate an value, interestingly). In Rust today, the compiler doesn’t know all the details of what’s going on. has a impl and so it’s quite opaque whether is heap-allocated or not. But we are working on various changes to this system in the Beyond the goal, most notably the Field Projections work. There is likely some opportunity to address this in that context, though to be honest I’m behind in catching up on the details. I’ll note in passing that Dada unifies and into one type as well. I’ll talk in detail about how that works in a future blog post.  ↩︎ This is kind of like C++ references (e.g., ), which also act “as if” they were a value (i.e., you write , not ), but a C++ reference is truly a pointer, unlike a Dada ref.  ↩︎ This goal was in part inspired by a conversation I had early on within Amazon, where a (quite experienced) developer told me, “It took me months to understand what variables are in Rust”.  ↩︎ I explained this some years back in a talk on Polonius at Rust Belt Rust , if you’d like more detail.  ↩︎ No closures or iterator chains!  ↩︎ As a teaser, I’m building it in async Rust, where each inference variable is a “future” and use “await” to find out when other parts of the code might have added constraints.  ↩︎ References are pointers, so those pointers may become invalidated. In the example above, points to the stack slot for , so if were to be moved into , that makes the reference invalid. The type system would lose track of things. Internally, the Rust borrow checker has a kind of “indirection”. It knows that is borrowed for some span of the code (a “lifetime”), and it knows that the lifetime in the type of is related to that lifetime, but it doesn’t really know that is borrowed from in particular. 4 Because references are not pointers into the stack, but rather shallow copies, moving the borrowed value doesn’t invalidate their contents. They remain valid. Because Dada’s types reference actual variable names, we can modify them to reflect moves. I’ll note in passing that Dada unifies and into one type as well. I’ll talk in detail about how that works in a future blog post.  ↩︎ This is kind of like C++ references (e.g., ), which also act “as if” they were a value (i.e., you write , not ), but a C++ reference is truly a pointer, unlike a Dada ref.  ↩︎ This goal was in part inspired by a conversation I had early on within Amazon, where a (quite experienced) developer told me, “It took me months to understand what variables are in Rust”.  ↩︎ I explained this some years back in a talk on Polonius at Rust Belt Rust , if you’d like more detail.  ↩︎ No closures or iterator chains!  ↩︎ As a teaser, I’m building it in async Rust, where each inference variable is a “future” and use “await” to find out when other parts of the code might have added constraints.  ↩︎

0 views
Langur Monkey Yesterday

LM Studio on systemd linger

The release of LM Studio 0.4.5 has introduced a much needed feature in this local LLM suite that has it much more attractive with respect to other similar projects. LM Link allows you to connect multiple LM Studio instances across your network to share models and perform inference seamlessly. By sheer chance, I was just playing around with setting up an LM Studio server in an old laptop that I planned to use for inference. I would connect AnythingLLM clients to it to make API requests. The timing of 0.4.5 was perfect for me, as I could now use LM Studio for inference directly, and forget about using up my own Tailscale network. But some setup was needed in the laptop. To make this work effectively, the LM Studio server needs to run in the background, start automatically on boot, and persist even when I’m not logged in. The LM Studio website provides the source of a service file . It suggests creating it as a system-wide service, which is weird, as the default installation method (at least on Linux) sets everything up in the user home directory. I modified it a bit to make things clean, as I want this to be a user service. It keeps the process tied to your user environment but, with a little tweak called lingering, allows it to run without an active SSH or GUI session. Here is the setup. By default, user services stop the moment the user logs out. To prevent this and allow the LM Studio daemon to start at boot and stay alive, run: Then, create a directory for your user services if it doesn’t exist: After that, create a file named in that directory ( ), with the following contents: Once the file is saved, tell systemd to reload its configuration and enable the service: If you want to load a specific model by default, add an additional line, like this: You can check the service status with . And that is it. You can now use your old hardware for inference with small local LLMs from any of your other machines.

0 views
Jeff Geerling 2 days ago

How to Securely Erase an old Hard Drive on macOS Tahoe

Apparently Apple thinks nobody with a modern Mac uses spinning rust (hard drives with platters) anymore. I plugged in a hard drive from an old iMac into my Mac Studio using my Sabrent USB to SATA Hard Drive enclosure, and opened up Disk Utility, clicked on the top-level disk in the sidebar, and clicked 'Erase'. Lo and behold, there's no 'Security Options' button on there, as there had been since—I believe—the very first version of Disk Utility in Mac OS X!

0 views