Latest Posts (20 found)

2026.34: App Snore

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 Sharp Tech video is on the turnover at DeepMind. Apple Makes Compromises in the EU. Ben has covered the angst surrounding the App Store since the beginning of Stratechery and was focused on Apple’s policies long before it was cool. Now that the company’s finally been forced to compromise in various forums — including a settlement this week with the EU, as well adjustments to its ATT policies in Germany — I thought the most remarkable aspect of Ben’s coverage on Wednesday was how incidental and boring it all seems in the shadow of the possibilities and concerns that exist everywhere else in tech right now. We had a fun conversation about that dynamic at the top of this week’s episode of Sharp Tech before turning to AI cybersecurity, vibe coding epiphanies, and more insight on writing with and without AI. — Andrew Sharp Truth (Social) and Reconciliation. Sharp China returned from its annual August hiatus this week, and in an episode that’s outside the paywall , we talked about various sources of U.S.-China friction before Xi’s visit to D.C. in September. Before that, however, we began in Korea with more questions than answers as Foreign Minister Wang Yi descended on Seoul in the wake of President Trump’s abrupt Sunday evening decision to reduce joint military exercises between the US and ROK. As for that Trump decision, in this week’s Sharp Text article , I used the Korea news as an opportunity to marvel at the exhausting economy of takes and theories that accompanies every foreign policy decision (and meme) under the current administration. — AS August Fun with the Clippers and Lakers . During the quietest period of the NBA calendar, there’s actually been quite a bit of news out of L.A. On one hand, we have a terrific mess as Buss family members squabble and Mark Walter’s DOJ-flavored cashflow problems have led to a shocking sale nine months after he initially purchased the team. On the other, Steve Ballmer and the crosstown Clippers might be in the (relative) clear after a 12-month NBA investigation into alleged salary cap circumvention. We discussed all of it on this week’s Greatest of All Talk , including frustrations with Clippers media coverage, what the NBA wants for the Lakers, and a memorable Top 5 segment about our top vacations.  — AS Stripe Acquiring OpenRouter, Aggregating AI?, Flipping the Business Model — Stripe is reportedly acquiring OpenRouter, an implicit bet on a future market of models and the chance at Aggregation. Nvidia Backs OpenAI Data Center, Anthropic News, Google Buys Spirit Airlines Data — Nvidia makes another deal, this time with a frontier lab; Anthropic’s revenue continues to amaze; and maybe data finally is oil. Apple Settles With E.U., U.S. App Store Fees, ATT Rules in Germany — Apple’s App Store is finally facing the reality of lower fees, and the EU should be satisfied with its work; it’s ok it’s late. So What Was Trump Saying to South Korea on Sunday? — A snapshot of Truth Social foreign policy and the take economy it inspires. More on Watermarking Apple Settles With EU How TSMC Uses Old Fabs to Make New Chips China Built 700 Waste-to-Energy Plants in 6 Years Wang Yi Visits South Korea; Remembering Zhu Rongji; US-China Ahead of Xi’s Visit; How China Monitors Foreigners August Fun with the Lakers and Clippers, Top 5 Takeable Teams or Players, Top 5 Vacations The App Store in the Shadow of AI, Offensive and Defensive Cybersecurity, Q&A on Financial Planning, AI Writing, American Sports

0 views
Unsung Today

Movie review: General Magic

★★☆☆☆ 2018, 92 minutes General Magic was a company started in 1990 by some of ex-Apple staffers, working on a pocket communication device and its operating system (Magic Cap, sporting a fascinating room user interface). The product launched in 1994, but swiftly failed in the market, similarly to and concurrently with its chief competitor, Apple Newton . Many alumni of the company – including Megan Smith, Kevin Lynch, Tony Fadell, and Pierre Omidyar – ended up having successful careers in tech after that, to a point that General Magic is referred to as “ Fairchild Semiconductor of the 1990s .” = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/movie-review-general-magic/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/movie-review-general-magic/1.1600w.avif" type="image/avif"> The eponymous documentary , released in 2018, was disappointing to me. Sure, it is well-edited, and particularly shines owing to a lot of archival footage shot during General Magic’s happy years. Unfortunately, we get to see none of the sort of details I was hoping to see: no pre-release interface or hardware, no discussion of product nuances, no solid reflection on the company, the culture, or the zeitgeist. The movie drops so many fascinating questions and avenues, but doesn’t really follow up on them: Unfortunately, I kept thinking of the movie as “generic magic” – a sort of interchangeable valorization of Silicon Valley’s “failure is secretly success in the fullness of time,” defaulting to romantic or rousing music, that must have felt obsolete even in 2018. It felt like the documentary could very well talk about one of the many other companies and efforts, which is frustrating, because there was something special and unique about General Magic. I also kept remembering The Soul of the New Machine , Andy Hertzfeld’s own Folklore.org , and even Halt and Catch Fire , all of which more adeptly interspersed personal and emotional drama with specific details you could learn from and take home with you. I think General Magic deserved more. (I do want to recognize that perhaps this wasn’t a movie for me. The documentary is free on YouTube if you want to check it out – it’s consistent throughout, so if you like the early minutes you might like the whole thing.) = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/movie-review-general-magic/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/movie-review-general-magic/2.1600w.avif" type="image/avif"> (To play with Magic Cap, go to Infinite Mac , click on Macintosh Garden tab at the bottom, search for “magic cap”, click on magic_cap_simulator.sit, go back to the emulator, double click on the Outside World icon, double click on Downloads, double click on the .sit file, wait for it to unpack, close the Downloads window, reopen it, double click on the Magic Cap Simulator icon.) #apple #history #movie review #review At some point, Andy Hertzfeld reflects on setting a bad example by focusing on small playful details instead of rallying the team to ship stuff. Where did this realization come from and did that change him as a person going forward? In hindsight, did the company benefit or suffer from the culture of freewheeling “superstars” who are also perfectionists? In a strange, brief vignette, a few people talk about not wanting to have any managers – but that is not picked up again or resolved in any way. How did the company manage to hire all of this past and future talent? Are there any repeatable lessons in here? During the launch, there is a brief slide with “whole person thinking,” which felt unique for a tech product reveal. Near the end of the movie, Kara Swisher talks about worrying how mobile devices can affect and perhaps even impair human-to-human communication. Those two threads are not connected. About the only lesson learned and spoken out loud comes from Tony Fadell, who says: “with the iPod, we iterated a lot faster.” Would this have mattered if the premise of the movie seems to be that General Magic was too early on the market anyway? There was a mention of a skeuomorphic room interface done pretty much overnight by Andy Hertzfeld. From the perspective of today, it is the device’s perhaps most distinctive characteristic, but it’s not covered more than that one mention. In another very rare specific example, there is a beat talking how iPhone’s (very controversial, early on) software keyboard owes its existence to General Magic’s team trying that first. How did whoever created it feel about it? An external observer suggests that General Magic missed the early ascendance of the web, but we don’t see anyone from the company reflecting on it.

0 views

In Purgatory Everyone Likes Crepes: My Time at a Greek All-Inclusive

I can’t remember the last time I was actually hot. It’s a thought that keeps looping through my head as I stand next to a children’s play structure in a Greek all-inclusive waterpark. The sun is beating down on an international community of mostly parents drinking watered-down cocktails out of plastic cups while their children scream and run in circles. Surrounding this little paddock of plastic is a lazy river, filled with mothers and fathers staring blankly into the middle distance as they slowly orbit the water toys. It’s all concrete and aggressively bright primary colors, suffused with the smell of gyros being cooked by a Filipino staff behind me. Living in Denmark, it’s rare for the sun to shine directly on you. Typically, everything outside looks like it has a blue filter placed over the lens—like how TV shows put a yellow filter over the camera to establish that you are now in Mexico. Sometimes in Copenhagen you might get hot, but then it will immediately start to hail on you, and you suddenly have a different, worse problem. Greece, by contrast, feels like the sun is noticeably closer to the earth. It feels personal, like a heat lamp pressed against your skull. My daughter has been playing peek-a-boo with a cute baby on a bench next to this water playset for long enough that I feel a moral obligation to go over and say hi to the mom. She’s a nice woman, watching four kids at a waterpark alone with a casual calm I actively envy. I’m a little stressed keeping eyes on just one, but she has four kids ranging from around ten to two, running around and disappearing beneath the waves, only to emerge just before I would panic. She has a small sunburn on the small of her back that I assume she either can’t reach or forgot—a small, raw triangle of red. We chat briefly. She asks where I live; I ask the same. I’m surprised when she answers Russia, mostly because I don’t get much exposure to Russians in Denmark. I clearly make a face without meaning to, because she quickly adds, "Their father is off fighting in the war." Ironically, I think she added this to head off me judging her as a single mother. Instead, revealing the father is a Russian soldier has made the part of my brain that regulates politeness completely short-circuit. What is the social etiquette for the wife and children of a military power you don’t support? I’ve never even considered this question, standing here in my swim trunks, my too-pale stomach exposed to a hostile world. I don’t want her children to be orphans, obviously. Neither she nor they did anything to start this conflict. But I’m worried that expressing vague positivity will end like my conversation with an Israeli in Copenhagen who took my neutral statement, "I hope the conflict ends soon," and responded with a wink and, "It will, with Trump at the helm." "I hope he comes home soon," I say, keeping my face perfectly neutral. She nods and resumes throwing a ball around with her children. She seems completely unaffected by thinking about her husband, which I think is actually the strange magic of the all-inclusive resort. It is a geopolitical anesthesia. The world is burning down, but here, the ice cream machine is still running. On most topics, I don’t consider myself a snob. I enjoy a Michelin-star restaurant, and I enjoy a nice slice of 7-Eleven pizza at 2 AM. I'll finish a thick, sad Classic of Literature and then immediately pick up Space Marines vs. The Metal Skeleton Wizard on the Moon . But on travel, I’ve always looked down on the all-inclusive crowd. Sitting one rung above a Carnival Cruise on the ladder of human decay, the all-inclusive always seemed like the most cynical way to say you had legally stepped foot in another country. My first real exposure to this was in Puerto Rico. I would leave my bespoke 20-room boutique hotel and scoff at the barbed-wire fence surrounding the American mega-resort down the road. "Why would you fly to the Caribbean to eat at a steakhouse?" I’d say, dripping with scorn to my wife, who would nod as we walked through dark neighborhoods on our way to eat dinner in someone’s actual living room that Google Maps called a restaurant. As I traveled the world, I saw these giant compounds everywhere. I swore I’d never become one of those placid, sunburned people wandering around a sculpted grass lawn, slightly buzzed at 11 AM. So imagine my surprise when I found myself finishing my second tequila sunrise before lunch, staring at a too-blue pool. The resort’s "activity crew" was out on Crepe Island—so named because it had a full crepe station on an island in the middle of the pool. "Really, it's a crepe peninsula," I say to nobody. Nobody cares. They are aggressively not paying attention to anyone else. This is not a community. A line of unlicensed, Disney-and-Nintendo-adjacent costumes are paraded out, with "Merio" closest to me. Kids kept trying to give Merio a high-five. I don't know if it was the suit or if the guy inside was just sick of his job, but he kept waiting too long to high-five the kids back, inevitably wacking them in the face or the back of the head as they moved on. Over and over, an excited child would run up, followed by a bizarre, lagging delay before the inflated hand would strike. "At some point, that's just hitting kids," I said to the ether. The woman next to me put her AirPods back in. My wife had booked this trip as a reward to our daughter. Having been a remarkably good sport as we dragged her to such famously child-friendly vacations like "A Sheer Cliff Overlooking Icebergs in Greenland" and "Endless Climbing Up and Down Stairs in Florence," we wanted to give her a chance to just be a kid. When we asked her what her favorite vacation was, she responded with zero hesitation. "Lalandia," she’d say, before resuming coloring in her coloring books with so much force you could see the head of the marker get pushed back inside the plastic casing. Since Lalandia is effectively a massive, indoor all-inclusive in Denmark, we figured the same concept in Greece would at least be a warm alternative. We boarded a chartered flight direct to Greece, my first time on a flight where everything was delivered in Danish. I felt like a spy hiding among the locals, fearful they'd discover the American among them. Safe from prying eyes, I was pleased to watch the Danes engage in behaviors they usually made fun of us for. Loud conversations were had, crunchy snacks were aggressively unwrapped, and general uncouth behavior typically shunned was suddenly fair game at 30,000 feet. Upon landing, the tour coordinator told my wife and me that we had to "run" to make our bus. My wife took off for the toilet; I grabbed the kid and the big suitcase and sprinted for the van. We then sat in the van waiting to take off for over an hour. What I hadn't realized in my heroic rush to the van was that I had left a small carry-on sitting in the middle of the airport. It was filled with snacks, coloring books, and also my wife’s wallet and passport. The first night at our all-inclusive was understandably tense. Variations on the word "idiot" were thrown around. The next day, we got the good news that the bag was safe and sound at the airport police station on the island of Kos. So while my family went off to the pool, I went to the lobby and called a cab. My driver arrived 30 minutes later and immediately asked, "Is it ok if you sit up front so we also take these beautiful people downtown?" The Scottish woman in the back blushed at this. I, lacking the social architecture to recognize warmth, simply thought: Wow, bold move saying that in front of her husband. I got into the passenger seat. This, as I realized later, totally broke down the driver-passenger social construct. After dropping the charming Scottish couple off in the downtown area, my driver started telling me literally everything about his life. For the next forty minutes, I learned how his brother had been a firefighter, then one day went on vacation to Vietnam, fell in love with a Vietnamese woman, and opened the only authentic Greek gyro restaurant in Hanoi. He had a booming, theatrical laugh and was poured into a skin-tight polo shirt. "Why are you going to pick up this suitcase your wife lost? DO WE EVEN NEED TO ASK?? HAHAHA! WOMEN!" Then he’d get deadly serious and remind me, "Children, they're the most important thing." I had spoken maybe six words at this point in the trip. I forced a laugh, silently calculating the statistical probability of being murdered and buried in a Greek olive grove. It would be a beautiful place to die, though I worried they’d use a photo of me from this trip—pale, squinting in a baseball cap—for the Netflix documentary thumbnail. Some true crime podcast would inevitably conclude I had it coming. At one point, he pulled the cab over to show me a flat patch of grass. "This is where I saved the island from a wildfire," he said proudly. I couldn't see any sign of fire; it just looked like a normal field with the grass crushed. I didn't say anything, as up to this point, the conversation had been delightfully one-sided. I had mostly sat sweating through my shirt, nodding. He told me how someone had thrown a cigarette out of their car, and it had started to smolder. He had stopped and used his legally required fire extinguisher to put it out. "It's good that I had this," he said, patting the dash. "This is why a robot can never replace taxi drivers." He then stared at me as if I were an assassin sent from Silicon Valley. "You betcha," I said, sweating. I wanted to assure him I wasn't there to replace him with an app. My amoral peers back home were already working on it, but I personally wouldn't kill his livelihood. Just people who looked and sounded exactly like me. I kept poking around silently instead, but then he caught me looking at the giant bulldozer sitting twenty meters away, its tracks leading directly to the field. I'm a genius like that. "Yeah, alright, also the bulldozer helped a bit to put the fire out. But mostly, it was my fire extinguisher." The bulldozer was merely an accessory after the fact. He then changed the subject by telling me that Tom Hanks had sat in his taxi "right where you are sitting." "Did you know Tom Hanks loves Greece and we love him? He is such a friend of Greece that we gave him a passport." Is Tom Hanks Greek? I thought, staring out the window. Why are there so many interior decoration stores? Is everyone on this island redoing their bathroom? "Tom is so nice, we love him." My brain returned absolutely no information about Tom Hanks, which frankly is typical of my mind. He clearly wanted me to respond with a Tom Hanks factoid, but all I could think to say was, "Yeah, his son was really good in Fargo ." "HIS SON? Who is talking about his son?" He took the conversation back over, explaining how Tom Hanks’s wife had sat in the back of the cab while Tom sat in the front. Weird choice, Tom, I thought, looking for a sign we were wrapping this trip up. When we arrived at the small airport, he parked randomly outside the main building, basically just the corner of the road that led from the airport back to town. "Wait, are you coming in with me?" I asked, confused. He nodded, saying it would "take way too long" if I went in by myself. Suddenly we were concerned about efficiency. He marched us in, knowing everyone who worked there. I found myself in a small police office that definitely didn't understand the separation of church and state. There was a massive crucifix on the wall, and each police officer's desk was covered with a Jesus mousepad and a large picture of the Virgin Mary. My cab driver and the police officer negotiated the release of the suitcase in front of me without bothering to involve me. At some point, I was told I could take the suitcase and get out of here. Nobody had asked me any questions except to quiz me about the contents of the bag. On the way back, we stopped for tea because, truly, what is a taxi meter at this point? We'd been in the car together for like two hours. He told me how his mother-in-law had almost died from a heart attack. "It's good that she could get to Athens in time," he said. He then told me how during the off-season he harvests olives from his family farm and has them pressed down the street. "It's heaven working the fields with your family." I imagined my siblings and I being asked to harvest olives in the beating sun and immediately envisioned four body bags in the shade of an olive tree. I nodded, staring out the window at a fire extinguisher store across the street, where what looked like a 12-year-old boy rolled a cigarette seemingly one-handed and lit it while sitting on top of a barrel. The long grass around the fire extinguisher store seemed primed for a fire. What happens if a wildfire hits a fire extinguisher store? I pondered, while my driver went on about the beauty of the Mediterranean or something I wasn't paying attention. Then we packed it up and went back to the hotel. "Thanks for a nice morning, Mark," he said fondly to me as I got out. My name is Mat. But I guess if you've saved the island from a wildfire, you can call me whatever you want. I got back just after Mini Disco. This was a one-hour dancing marathon for the kids in the semi-enclosed theater. With two fully manned drink stations on either side of the stage, it was an opportunity for children to dance while their parents drank like an asteroid was imminent. The songs stayed the same every night, but on this first night, we were going to learn a valuable lesson: Always buy the t-shirt. Apparently, while I was learning the ins and outs of the Greek cab business, a nice woman had asked my wife and daughter if they wanted to buy a t-shirt for the Mini Disco. My wife, smelling a tourist scam, had hard-declined. What she didn't realize was that the climax of the Mini Disco was a formal t-shirt presentation ceremony. Each child's name was called, they were presented with a t-shirt, and then they were allowed to hug Leo the Lion. My daughter didn't understand that she didn't have a t-shirt. So, when the name "Eleanor"—which is not her name—was called, my daughter hopped up and snagged the shirt. This meant my wife had to rush onto the stage, rip the t-shirt out of our daughter's hands, and hand it to the sheepish little girl whose shirt it actually was, all while holding a cocktail. It was a masterclass in parenting under the influence. The next day, we were on the hunt to put in an order for the t-shirt, having made the most serious promises parents can make to a child. After we chased down the red-haired French woman running the kids' merch table, we went to the main pool. She didn't seem surprised to see us come crawling back. I got the sense the first day she was doing the sales pitch, then after that she just waited for us to come to her. There is a weird etiquette to pools and British people. They will rush out the second you are legally allowed to put a towel down on a chair, meaning from 8 AM to 1 PM, there isn't a single open seat. The British treat pool chairs the way trench soldiers treated no-man's-land: as hotly contested territory worth dying over. But if you are lazy like my family is, you just wait. They start to leave the pool around 1 PM, and you can get a great seat with zero work. The next day, you repeat the entire cycle. That evening, kiddo got her shirt. It was a proud moment; she clutched her blaze-pink t-shirt to her chest and teared up with pride. Soon, the days started to blend together. At some point, we all got an emergency text message telling us about wildfires on a neighboring island. I assumed the resort staff would need to calm down the crowds, as you could pretty clearly see the smoke from the fire. The sky was turning a dark, orange-brown in the distance, and the air smelled like burning rubber. Nobody cared at all. A thousand people looked at a Greek text message they couldn't read, put their phones down, and picked up their beach reads. The apocalypse was met with a shrug. As an allegory for global warming, there is something particularly bleak about people dancing in a pool to 90s boy band hits as a thick plume of wildfire smoke shoots up into the sky. Thankfully, here nobody pretends to care about anything, so I was able to slip back into a soothing apathy. In a world that was constantly asking me to pay attention to some fresh horror, this was a place that asked nothing of you. Toward the end of the trip, we decided to head down to the small town and were dropped off at Dolphin Square. We started walking around, looking at Google Maps to see what we should look at. There was a Roman House, which is basically an empty lot full of pieces of old Roman architecture and a sign saying I needed to pay 10 euros a person. Since nobody was there to collect this 10 euros, the sign felt more aspirational than practical. Someone should pay this Greek island 10 euros, but not today, I guess. But I looked at the old rocks. My daughter was unimpressed. She looked at the ruins, looked at me, and asked if she could get ice cream. "Denmark has a lot of old stuff," she said, which, in her defense, is true. We walked around a bit more, buying little tourist trinkets. I'll never understand who buys the t-shirts that fill the small streets of these towns. Who is the demographic for a shirt that says "I heart my boyfriend"? And more importantly, where is he? Does he buy the t-shirt for you before you go on a solo trip without him? But we went to a small restaurant and had a proper meal for the first time in days. Despite the heroic efforts of the staff at the resort, it was actually hard to eat there meal after meal. The culinary philosophy seemed to be "cook the will to live out of it." Everything was either fried and dried out beyond belief, a hard puff pastry, or so bland you couldn't really tell what was going on. The lamb sorta tasted like the chicken, which tasted a lot like the pork, which tasted like a cry for help. At one point, we went to an Asian-themed restaurant on the resort, and I was served "duck with Chinese pancakes." The duck was well-cooked, but the pancake was an Old El Paso flour tortilla. I couldn't help but feel like the duck died for no reason. At one of these meals, where my daughter pounded another plate of french fries and pizza, a British woman at the table next to us told me how her entire family looked forward to this trip. She started to tear up as she explained that she and her husband had worked extra hours this year to make it so their kids could come with them. "It just makes me burst with pride to think about," she said. As she spoke, one of her kids sat beside her, wearing noise-cancelling headphones, staring at an iPad, and methodically eating an entire pepperoni pizza without making eye contact with another human soul. By the end of our week, I was eating meals of plain bread with watermelon and coffee. My daughter was consuming what looked like a kilo of Nutella, and my wife and I settled down for another cycle. We only ended up going to the actual beach, which was beautiful and maybe 200 meters from our hotel room, once. The ocean was beautiful, with rolling hills in the background, perfect warm water that was the saltiest water I've ever been in. It was like swimming in a giant, warm tear. Everyone but me hated it because it wasn't as nice as the pools. "Ugh, there are ROCKS!" my daughter shouted, upset at the audacity of the ocean for existing. Honestly, the rocks hurt a fucking ton, but I was too self-righteous to admit it. "Let's enjoy nature, everybody!" I yelled, bleeding from the feet. I thought by the end of my time with these people that I would come to think less of them. I expected to leave despising their complacency. Instead, I found myself weirdly protective of these folks. They are just trying to make some childhood memories with their kids, trying to manufacture something, anything that looks like a normal childhood in a world burning down. I won't lie, the all-inclusive life isn't the life for me. It is a place out of time, where the enjoyment of it requires a total suspension of your relationship to the outside world. But I do now understand the appeal of not being challenged. In a time when everything is being questioned and every tradition and norm is falling apart, this is a callback to frankly an easier time to be alive. And we ended up getting the t-shirt, which, when you break it down, is really the most important part.

0 views
matklad Today

Rust Glancer

Rust Glancer , a functional LSP server for Rust which uses two orders of magnitude less RAM, is incredibly cool. Go check it out! This post started as a comment on lobste.rs, but I figured it out that it’s better to publish it somewhat more prominently. Don’t expect polished writing though! Some thoughts: rust-analyzer uses rowan for syntax tree representation Yeah, rowan is garbage :P I was really thinking about And Rowan is pretty good for that. But that’s 1% use case. The 99% use case is all the code in your 6666 dependencies which you won’t ever look at, but which needs to be at least shallowly analyzed. Even for incremental tool whose main goal is refactoring, the primary AST structure should be just a list of arrays. There might be a real post about that at some point, see https://youtu.be/G93oYL1ry70 as a teaser. Rust workspaces genuinely have a lot of information that must be indexed: thousands of functions, structures, traits, relationships between these, function bodies and statements in them, etc. Each of these needs to be analyzed and remembered, and you can’t really cheat if you want to have things like “find all references to this structure”. If I understand correctly, Rust Glancer wants to process each function body. I think that part can perhaps be made lazy (but not incremental!) with little overhead? Index all items, but, for functions, do only the currently opened file? This might combine some of the better parts of both worlds. Would be interesting to compare memory usage with Rust Rover. Net of the IDE GUI itself, I would expect RR to be more compact. Some features are unlikely to be supported though, such as build scripts / proc macros support via proc macro invocation I might be rationalizing/misremembering things, but IIRC it’s exactly around adding proc macros that the thing began to feel unreasonably bulky. Expanding proc macros is slow as we are running real code, we can’t really do normal IDE cheats. And proc macros generate a lot of code. At one point I measured, it was like 30% of rust-analyzer binary size was attributed to JSON parsing code. If no one sees the code, it can’t harm anybody, right? One potential approach here is to pull the Sorbet trick, where you don’t run meta programming at all, and instead have a plugin interface to “explain” the effects of what that would have done. Instead of running serde, we just add a shim that injects with an empty body. I’m not sure why, but in rust-analyzer I’ve observed that when agents edit the code, inlay hints can get out of place Rust analyzer’s core data model is very pedantic about always observing consistent snapshots of the code, and does its best to ensure that the language client and server have a shared, strictly serializable view of the world. It’s a shame that LSP doesn’t allow that to be correct , only heuristically right , unlike the older Dart Analyzer protocol, which has sound data synchronization. However our implementation of file watching is sketchy! First, there are two backends: we can ask the editor to do watching for us, or we can use server side watching. Try changing this option and see if it helps? But then, yeah, my recollection is that our native watcher’s API was fundamentally racy, and I didn’t do the messy platform-specific work of making it correct. But the main thing I want to write, and why I moved from the cozy lobste.rs text area to the luxurious comforts of an Emacs buffer, is that right now rust-analyzer is a bit like that half-drawn horse meme, except that it’s only the head half of the horse. One Big Idea of IntelliJ is that it’s PSI API (essentially AST with resolved types) is really an interface, and there are multiple provides. And in a typical usage, there’s at least three backends in play: This is how I think such things should work. rust analyzer shouldn’t use salsa for all those 6666 dependencies you still haven’t looked at. It should just use rustc’s .rmeta files, switching to salsa, transparently, only when the user starts messing around their folder. The prerequisite for that is defining the abstract API for accessing Rust code. That was always the plan, and we did start on that at some point: https://hackmd.io/ytd82QNiT_Ku2XFr1EAtiQ rmeta-transparent – source code might not be available for some crates, the API should support pre-compiled rmeta files as inputs. But I don’t think that work was ever completed. This still seems to me to be the lowest-hanging watermelon here — split the world into arcy-pointy incremental tip of the iceberg, and mostly read-only, on disk, compact, dark, moist breeding ground for supply chain attacks. Such glance analyzer architecture would be great, imo! incremental parsing, incremental, DOM-mutation style refactorings, For the files opened in the editor, actively modified by the user, the PSI is backed by the concrete syntax trees. For the rest of the project files, the PSI is backed by the so called Stub Tree, a compact on disk representation storing only the “externally visible” parts of the file (so, without function bodies). If the user navigates to a new file, its PSI transparently switches from stubs to syntax tree. For dependencies, the PSI is often backed by the compiled .class files, produced by javac. If you navigate there, the IDE just decompiles stuff four you! Super cool!

0 views

The Man Who Knew Too Much

The Man Who Knew Too Much is a film of peaks and valleys. There is little argument that it is a good film; whether you place it amongst the highest of Hitchcock's work depends on just how much you value the stratospheric heights it reaches, and whether they overcompensate for the lulls. The film is never weak, but it is weak for Hitchcock in parts. Watching it for the first time, and knowing that it is a Hitchcock film, you feel as though you don't quite need all the foreshadowing and lampshading. As it progresses, you can't help but feel a sense of déjà vu with his other work — remarkable for this film as compared to the parts of his filmography not considered his absolute best. As a remake of his own 1934 work, and something relatively mid-career for him, it is very much him in his bag, doing what he does and what he is well known for. Compare this with, say, Family Plot , where your mileage largely depends on how willing you are to go along with him doing something much shaggier than usual. Put another way: this is the first Hitchcock film where I found myself not once, but twice , checking how much time was left in the movie and being surprised that there was so much still to go. But those dizzying heights. There is, crucially, the ability Hitchcock has to wring noteworthy performances from the Jimmy Stewarts of the world — to see something new and interesting in a face you have already seen so many times. I say this without consulting any of my prior notes, but my gut reaction was that this was my favorite Jimmy Stewart performance I have ever seen. He plays a man who fits perfectly the definition of fumbling . Hitchcock uses his frame for great gags, especially in the first act. But there are two scenes in particular where you see Jimmy Stewart as something an actor of his caliber is almost never shown as: a completely broken man. First, the close-up of him holding the corpse of a dying man, trying to process on many levels the mistakes and errors he has made over the past few days. And then a scene that is grotesque in many ways, but not unrealistic, when he coerces Doris Day — his wife, who must be said is consistently much smarter than him throughout the film — to take a fistful of tranquilizers before he delivers the news that their son has been kidnapped. For all the love I have for Cary Grant, he tends to have a certain problem in Hitchcock films of being too starkly charming in the scenes where terrible things have happened to him. Jimmy Stewart crumbles, and stays crumbled, until the very end. And then, of course, there is the VistaVision and the scene work. I am not smart or well versed enough to talk about the technology and how Hitchcock used it, but the aesthetics are perfect and gorgeous. He relies a lot on static shots, especially when we are first introduced to Marrakesh, that — like a discordant note held for slightly too long — usefully upset the viewer. But where I must end this review is, I imagine, with the set piece that most people think about when they think about this film: Albert Hall. Five minutes of opera and those aforementioned static shots, not a single line of dialogue, but stress building and building and building — for me, it is indelible, and so powerful that even after I forget the silly international spy bits, I know I will remember it for years to come. I think this is correctly placed in the mid-tier of Hitchcock's canon. His best films are tauter and have more things to say, tauter and carry more opinions than this one does. But a middle-tier Hitchcock film is still a very good film. And if I got to watch something this good every evening for years to come, I would consider myself a very lucky filmgoer. 8 out of 10. One last thing: Doris Day was great. The script did not really give her much to display any sort of range, despite the character herself being very competent and capable and, again, much smarter than Jimmy Stewart's — but there's just not a lot for her to do. 1 Honestly, the same could be said of Jimmy Stewart's character, and to a certain extent that's why parts of the film drag as much as they do: you get the sense that our protagonists are, up until that Albert Hall scene, passive observers more than they are agents of the action. Not a sin in and of itself, but it exacerbates the drag in the middle of the film, because everyone is just going through the motions. But Day's performance in that tranquilizer scene is unimpeachable — and, as with Jimmy Stewart, not something you're used to seeing from an actress of her stature.

0 views

Readers can't identify watermarked AI text

In the last few weeks, I’ve been complaining that everyone is wrong about AI watermarking: it isn’t really anti-consumer and it doesn’t make the outputs any worse. The watermarking papers demonstrate 1 that this is true, but I thought it might be interesting to put it to a practical test. Given examples of watermarked and unwatermarked answers to the same prompt, could readers tell which is which? To find out, I vibed up 2 https://sgoedecke.github.io/watermark-quiz/ , a static site that quizzes readers. I used Qwen3-30B-A3B-Instruct-2507 on a rented H200 to generate thirty responses: three responses per question, one of which was secretly watermarked with SynthID-Text. The rented GPU cost around two dollars. To measure results, I just sent users to a different page for each score, and aggregated visitors-per-page in my analytics 3 . This would be easily spoofable if anyone cared enough to do so, but for a casual test I think it’s acceptable. The first round of traffic I got to the quiz (278 participants) had these slightly puzzling results: Pure random choice would lead to an average score of 3.33/10. However, the mean score here is 3.92. There is indeed a spike around 3/10, as expected, but there’s also a second weird spike at 6/10. Why is that? It turned out that the SynthID response was option A in six of the ten questions, so users who just selected the first answer for every question would get 6/10. Oops. I re-shuffled the questions and got these results: Now the mean is 3.4/10, much closer to the expected 3.333. There’s no spike around 6. We only had 73 people take the quiz after I shuffled the questions — most people saw it and took it immediately after I posted it to my LinkedIn and Hacker News — but given the previous results, I think that’s still enough to feel confident that people were just guessing randomly. So no, people can’t identify the presence of AI watermarks . Obviously this wasn’t exactly a scientific study, but it’s still pretty suggestive. If watermarks were really choosing random words that the model would never pick, you’d be able to sometimes tell from three side-by-side responses which one went down the weird watermarked road, right? I also hope that something like this can serve as a persuasive tool: if you’re worrying about what impact watermarking is going to have, and your intuition is unmoved by the mathematical explanations, having a read of the watermarked and unwatermarked responses might convince you that there’s really no difference in quality. The one-sentence explanation for why is that AI models already randomly select from a handful of top tokens, and watermarking just replaces that random choice with a bias that is predictable while still being equivalently “random”: as a simple example, instead of “pick randomly from the top three tokens”, you could do “count the letters in the previous ten tokens, take mod three, then pick that token”. Some notes from the vibing: GPT-5.6-Sol put extraneous text all over the page I had to get it to remove, it chose the now-very-recognizable styling that I had to rip out, and it built some kind of weird Javascript-driven static site instead of just the cross-linked pure HTML thing I would have built by hand. It took me about an hour (although I did maybe ten minutes of actual work). Umami, hosted on PikaPods. For my blog, I do also pay for Netlify analytics because I find JS-based analytics misses >50% of technical users, but for stuff like this Umami is fine. The one-sentence explanation for why is that AI models already randomly select from a handful of top tokens, and watermarking just replaces that random choice with a bias that is predictable while still being equivalently “random”: as a simple example, instead of “pick randomly from the top three tokens”, you could do “count the letters in the previous ten tokens, take mod three, then pick that token”. ↩ Some notes from the vibing: GPT-5.6-Sol put extraneous text all over the page I had to get it to remove, it chose the now-very-recognizable styling that I had to rip out, and it built some kind of weird Javascript-driven static site instead of just the cross-linked pure HTML thing I would have built by hand. It took me about an hour (although I did maybe ten minutes of actual work). ↩ Umami, hosted on PikaPods. For my blog, I do also pay for Netlify analytics because I find JS-based analytics misses >50% of technical users, but for stuff like this Umami is fine. ↩

0 views
alikhil Yesterday

How to not burnout

As someone who has experienced burnout, and has talked to many people who have experienced it, I can tell you that it’s tough to recover from burnout. It may take a lot of time and money and can cost you your job or even your profession. However, it’s much better to prevent it by taking some precautions and following simple rules. It requires less effort, helps prevent burnout and costs less. You won’t find a secret recipe or a silver bullet here. I genuinely believe that burnout can be prevented by following a few simple rules, or better yet, by treating them as hygiene. Doing the same thing every day can become extremely boring. It’ll slowly kill your motivation and you start hating your job. Automate repetitive work . Reduce the maintenance burden. For example, if you find yourself handling the same type of ticket over and over, build self-service workflows, or at least write instructions so other engineers can handle it without bothering you or your team. After you spend enough time repeating the same action many times, you’ll likely end up being good at it. Your colleagues will notice that and you’ll be asked to do this action even more. Boredom is another risk of repetitive tasks. If you find yourself bored with the same work, problem, technology or anything else, find a new challenge: something new to discover and solve, a new problem, a new tool or skill to learn. Remote work, lack of verbal communication, and absence of feedback could lead to loss of sense of reality, causing you to start doubting our skills, competence, and impact. Ask your manager and your peers for honest feedback . Accept it. Your self-doubt will likely disappear and you’ll get some direction on how to improve your skills and grow. Being motivated and productive at work will lead to big results, doubtlessly. However, for most people, life is not limited only by work. Chronic overworking will damage other areas of your life. While your productivity could benefit in the short term, in the long term you’ll suffer from tiredness, lack of motivation, and bad sleep. So try not to overwork when you can . If you had to overwork because of a strict deadline or an urgent delivery, try to compensate it by taking days off soon afterward to recover. Don’t check your Slack/email after working hours . You need a real pause. Reading work-related messages will keep your brain focused on solving problems instead of resting and being present with your friends and family. You are still working, and, in fact, overworking. If you can, I’d recommend having a separate smartphone for work-related things. You may say: “But if I don’t check Slack/email, I might miss something important and urgent.” I believe this concern is overestimated. Most communication can wait until the next morning. For really urgent matters, on-call practices should be in place, and another tool should be used, like PagerDuty. Use your paid time off days . I’ve met people who don’t use their PTO days; they stack up until they vanish. Disconnect from your work, get new ideas, travel and catch up with other areas of your life. Visit friends and family. It’s a basic necessity. It’s not surprising that minimum vacation days are required by law in many countries. Get regular physical activity. I’m not saying you should master volleyball or run 10 km every day. It could be anything convenient for you, like swimming in the sea, doing yoga, walking 10,000 steps, hiking – whatever suits you best. It can help to relieve stress and clear your mind. It’s especially useful to do it just after you finish your working day, to switch contexts. Physical activity can be a smooth bridge from your work back to your life. Have a hobby. Find something you’ll enjoy doing. It’s better if your hobby has nothing to do with your job – ideally, it should be something totally different. For example, I spend all day sitting at home in front of my computer as a software engineer. So as a hobby I’d choose something I’ll do away from home and with other people. Like going to improv comedy classes, or playing padel, or playing board games. Imagine loosing your job or burning out and when work is the main part of your self-identity. The crisis will hit you hard. If you have no idea what could be your hobby, go and try new things. Ask your friends about their hobbies, ask whether you can join them. Look for activities online, on platforms like Meetup. Think of things you enjoyed doing in your childhood. It’s easy to fall into workaholism, start overworking, forget to recharge and neglect other aspects of your life. Keeping work and life balanced takes effort. Find what works for you. What do you do / don't do to not burn out at work? Tell the world!

0 views
Jim Nielsen Yesterday

A Sloppy Interface Is a Security Liability 

In his talk “Why AI Is Breaking Software Security As We Know It” ( my notes here ), Feross Aboukhadijeh talks about the Axios npm incident and how the maintainer got phished by succumbing to (amongst other things) a faux Microsoft Teams interface: this is the kind of thing that AI makes easy to do, because it can vibe code that whole fake Microsoft Teams interface pretty trivially You’ve probably seen these: interfaces designed to look like some other product in order to provide a facade of authenticity and exploit someone. What struck me in listening to Feross was this idea of how the quality of your interfaces can be a protection mechanism against attackers. I don’t know if I’ve ever heard someone say that out loud — interface and interaction design as a security control — but I’m saying it. Now, of course, not everyone will consciously notice the level of polish that world-class professionals imbue in digital interfaces. But some will. Personally, I’ve always used the quality and care of digital experiences as a heuristic for judging authenticity — and competency to be honest, e.g. “If this UI is so bad, what else will surely be bad?” Granted, it was a much more dependable heuristic before AI came along. But even now, I can still suss out slop and carelessness which is a skill that continues to be a reliable, protective form of digital literacy (for me). That’s all to say: a sloppy, careless approach to interface design not only hurts your brand in terms of customer perception, but it can be an attack vector. The easier it is to sloppily reproduce what you sloppily ship, the easier it will be for your product or brand to be leveraged as a vehicle for exploiting your customers. If everything you make was produced from a single prompt, then everyone else is one prompt away from imitating you. The easier something is to make, the more likely it’ll be in the genre of “easy to exploit”. One way to protect yourself (it’s not the only one way, security is never a binary “you are / are not secure”) is to do that extra work to make your experiences go above and beyond what you can easily get out of an LLM. The protection here is having an interface and experience that is hard to replicate with the same level of fidelity that discerning users will notice — things like micro-interactions, loading behavior, UI copy and voice, handling of edge-cases, etc. That’s the stuff that’s hard (and expensive) to fake because it’s hard (and expensive) to notice you need to fake it. tl;dr — Fidelity to craft is not only valuable from a product standpoint, but it’s also valuable from security standpoint. If attackers are going after low-hanging fruit, your fruit will be harder to reach if it’s up high. Reply via: Email · Mastodon · Bluesky

0 views
Unsung Yesterday

Zalgo: The good, the bad, and the very, very ugly

Have you ever seen this? The best way to predict the future is t̷o̶ ì̴͇n̵͓̆v̶̝̕ȇ̷̝͈̩͊̇̾̄̂̀̈̔̀͛͋͆̓͒͘͝ͅn̸̦̙̣̤͓̜̼͙̲͔̺͚̮̬͆̇̇͐̇̽̒̎t̵̮͎̃̒͒̋̂̏̒̀̿͌͗̄͑̀̀͒̈̚͠͝ ȋ̸̧̛̭̠͈̰̰̦̹̥̜̖̈̂̀̽̿̋̊́̇̍̓̆̉̄̄̊͊̒̎͋̂̒̍̽̄͝ͅt̶̨̢̺̱̻̭̣͉͕̥͚̯͍̣͕͔̬̥͔̘̼͌̉̀̄̊̆͛̽̍̐̔̐̀̾̋̆͒̏̏̋͋̽͗̌͋͗.̸̧̨̧̡̢̪͙̦͙̝̜̦̞̳̤͖̟͍̮͖̘̙̳͉̳̲̲͉̠͎̽̍̓̒̅̿͂͑̎͊̋͒̈́̅̈́̆̽̒͛͐͛̉̀̈́̈̉̏̏̋̒͘͝͝͝ In the lore of the web, this kind of a strange glitchy text is known as Zalgo : Zalgo is a meme where a popular picture/​comic is edited in a way that “corrupts” it, producing scary results. The term “Zalgo” refers to the being apparently responsible for the corruption, whose name is uttered by its victims in an eldritch manner. I’ll let you read up on that at the above link if you are curious, but what’s interesting for us here is that… Zalgo is text. You can grab the line above. You can copy and paste it. You can even try to edit it. But… what is that, and why is it possible to construct text this way? In Unicode, ä is a completely independent character from ą, and they are both completely unrelated to a – any type designer treats them as a variant of the same base letter, but there’s nothing preventing them from making them look very, very different. But now think of the Vietnamese language, which has six tones mapping to six accent characters , and many of them can be combined into pairs: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/zalgo-the-good-the-bad-and-the-very-very-ugly/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/zalgo-the-good-the-bad-and-the-very-very-ugly/1.1600w.avif" type="image/avif"> This gives us 104 accented letters, and 30 doubly accented letters, just for this one language. Sure, you can imagine adding all of them as independent characters, but at some point another idea appears on the table: What if we just allowed a system where you can add an accent to any letter? Instead of outputting ä as one letter, you could output a followed by ̈  , which then would be recombined by the rendering logic into ä. And to get two accents, output a and then ́   and   ͆  , to get á͆. Now, the zero-one-infinity rule says that once you open the door to two, you might as well allow three or even more. Add to it the fact that some accents go under the letter, and here you go: perfect conditions for the Zalgo meme that just creatively stacks up accents one after another – not for communication, but solely for aesthetics. Today, there are a whopping 122 combining diacritical marks used in all sorts of occasions, and Zalgo generators grab many of them. A fun thing to try in one of them is to let it do its thing, and then keep pressing Backspace: Now you might ask, why do separate characters exist for ä and ą then? Why isn’t every accent combining? Two things: history (some pre-combined accented characters existed for as long as movable type was around) and complexity (combining accents are harder to process, to display, to edit, and even to design). There were many debates around this – you can open the History box on the above Wikipedia page and pore over the old documents to learn. (As a matter of fact, today all Vietnamese letters exist as precombined characters, too.) A few bits that might be useful to know: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/zalgo-the-good-the-bad-and-the-very-very-ugly/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/zalgo-the-good-the-bad-and-the-very-very-ugly/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/zalgo-the-good-the-bad-and-the-very-very-ugly/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/zalgo-the-good-the-bad-and-the-very-very-ugly/4.1600w.avif" type="image/avif"> Eagle-eyed among you might have noticed that ä and á͆ look different above. As far as I understand, if the combination of a letter and accents isn’t supported by the current font, the entire combination falls back to a different font , rather than picking bits and pieces from different fonts. There are even more combining characters , and emoji use a similar system to add skin tone modifiers, gender, or turn a woman next to a fire truck into a female firefighter. Lastly, I found this warning on the very Fandom page that explained Zalgo amusing: Do not post Zalgo text in the discussion area or anywhere else on the wiki. Doing so will subject you to a ban. Every warning tells a story; it seemed like more people were perhaps infatuated with the glitchy text than expected. #encoding #typography Zalgo is a good reminder that while it’s hard to contain text , you can at least crop it – often you might see things like these, where in some places Zalgo is allowed to roam free, and in others the text is clipped so three or more accents fall outside of the clipped area. Eagle-eyed among you might have noticed that ä and á͆ look different above. As far as I understand, if the combination of a letter and accents isn’t supported by the current font, the entire combination falls back to a different font , rather than picking bits and pieces from different fonts. There are even more combining characters , and emoji use a similar system to add skin tone modifiers, gender, or turn a woman next to a fire truck into a female firefighter.

0 views
David Bushell Yesterday

Ruminations on notifications

I’m on annual leave next week. Now would be the ideal time to drop premium rage-bait and walk away. “One browser tab is enough” was drafted but due to a tragic accident we are all spared. This sideways look at notifications should be more relatable. When I pay using NFC I’m annoyed twice. First by Apple Pay, then again when my banking app catches up. Can’t they decide between themselves? I don’t need two reminders about the groceries I bought a minute ago. Maybe I can disable notifications for either one, but then I might miss real fraud alerts. Notifications are a chore I could do without. Notifications are a core feature of needy programs . Every app wants to be the centre of attention. They can’t wait to tell you about their new features. Presumably in-app notifications are the new trend because OS level notifications are easily blocked. Vivaldi ruined my browsing experience for a long time. That annoying “toast” wasn’t dismissible. It crossed the line of death and looked suspicious. Eventually it was fixed by moving into the tab bar. I recently returned to Sublime Text to avoid modern apps that were too needy. In response to my post, developers were keen to laud their command line supremacy. I don’t disagree but the CLI isn’t immune to notification nonsense. Every time I open Neovim I get stopped. Guess what happens when I press enter? Nothing! How about telling me what the command is to update the damn plugin?! Dear devs, updates may be your life, they ain’t mine! The web platform demands that anything native apps can do, the web must copy. There are good arguments for this. The counterpoint is terrible implementation. Browser vendors have done a dismal job at designing the user experience around push notifications . “This website wants to send you notifications, allow?” Does this still pop up before a page has even loaded? I wouldn’t know. I blocked that years ago without thinking twice. My advice, look for this: — and block wholesale without exception. In all my years of building websites I’ve never had a single client request or even consider notifications. Not one project that scoped in such a requirement. Apple held out for declarative web push in Safari citing their usual privacy theatre ( lol ). Apple aren’t fans of silent push with no visible UI. I reckon their actual trepidation is their unreliable cloud syncing infrastructure. When I tested it was 50/50 on whether a notification ever arrived via Apple. Mozilla’s servers are rock solid. One rainy day I ran an experiment to send large data split across many hundred web push payloads. I was able to clock kilobytes per second. This is awful abuse of the API. Apple might be right about silent push… Proton Mail was one of the few mobile app that I allowed notifications. My inbox is usually rather chill, except when Proton spam me themselves . Alongside my public addresses I use [redacted]@ for important accounts. I configured a folder to send mobile notifications for this address only. It worked for years. Then one day the spam notifications began. Spam that had already been flagged and filtered into trash (sent to any address). I reported this bug to Proton Support in May and was told: If we have any relevant information to share with you, or if we have any questions, we will follow up on this support ticket. I never heard back. Notifications remain disabled. Today my phone is almost entirely notification free unless I get an SMS from family. Oh, and Apple pestering me about iOS 26 several times a week. My iPhone will remain on iOS 18, thanks. Apple sure love their dark arts and deceptive patterns. There is no option to stop this constant nagging. If other apps tried it I bet Apple would delist them. This ain’t about security, I get iOS 18 updates. UK Government got trigger happy with their alert system. As with all mobile alerts of this nature, we’re reminded that abuse victims are at risk . This one also led to fire departments across England and Wales having to remind people their neighbour’s barbecue is not an emergency. As Robb Knight noted: “there is nothing actionable in the alert” . Unless you count “Search gov.uk”, so I did. The more information provided was: Sent by the UK government at 7:01pm on Friday 14 August 2026 This alert was sent to England and Wales. Surrounding areas might also have received the alert. Emergency Alert - GOV.UK Thanks, Government. That could have been an email. Why don’t these alerts respect my volume setting? Scared me half to death! If they have to be all or nothing, reserve them for zombies or higher. And that’s the problem with notifications. There is rarely the granular control necessary to make them useful. Most senders cannot be trusted to used them responsibly. The temptation to abuse direct access to people is too much, especially for men with guns . If I ever allow notifications to begin with I disable them indefinitely the first time an app cries wolf. Every app cries wolf eventually. Life is so much better when I go seeking information at my own pace. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
Karboosx Yesterday

What an AI-First Programming Language Would Look Like

Current programming languages are full of syntax that AI doesn't really need. If AI is the one writing the code, why bother with brackets and commas? I explore two ways we could redesign languages for machines: either super low-level assembler or very verbose natural language. Let's look at why we need to optimize this! ;)

0 views
Unsung Yesterday

Got your back, pt. 7

Nice recent addition to Gmail – a little warning if you’re replying to a thread you were BCC’ed on. = 3x)" srcset="https://unsung.aresluna.org/_media/got-your-back-pt-7/1-framed.1600w.avif" type="image/avif"> Please note that I’m not necessarily endorsing the execution details, as I consider Gmail kind of a clunky operation overall. You can’t swat the message away with a swipe, the wrong quotation mark is used, and I’m perplexed about the location of this message – something tells me it was really cheap to do it this way rather than put it close to the recipient field, to help you understand the relation. But still, I appreciate something shining at least a bit of light at the complex relations between To, CC, and BCC. #google #got your back

1 views
Jeff Geerling Yesterday

Getting the Steam Deck LCD working on a Raspberry Pi

The BOE TV070WXM-TV0 LCD used in the original Steam Deck can be had for around $30. It's a serviceable 7" touchscreen with 400 nits of brightness and a resolution of 1280x800 (for a sharp 216 ppi). The specs are a lot nicer than the Pi 7" Touch Display , which costs twice as much, with giant bezels and half the resolution! Until today, the Steam Deck LCD didn't work with a Raspberry Pi. But the folks at Scandent were trying to standardize on a mass-market touchscreen for one of their own devices, and built a Linux kernel driver for it which they intend to upstream.

0 views
マリウス Yesterday

Flipper BUSY Bar

Yes, it is in fact real, I’m holding it in my hands, and after what feels like years of Flipper teasing everyone with this ominous device in various online posts, I can finally confirm that it is real. The BUSY Bar is a 250 gram desk device by Flipper Devices , the company behind the Flipper Zero and the still very much in-development Flipper One . It’s basically a little display that shows various things on a 72x16 RGB LED matrix, and as of writing this it’s main selling point is that can run a Pomodoro-style focus timer , and that it has a ful-blown HTTP API that’s available over USB, over the local network and over the internet, that let’s you control this thing. The BUSY Bar has a five-position selector on the top, that switches between the two focus modes ( BUSY and CUSTOM , which are functionally identical and only differ in their defaults), a OFF position that in reality is more of a sleep mode which turns both screens off, an apps position that currently only holds a clock, and a settings position for, well, the settings. A large mechanical button in the middle starts and pauses a session, a scroll wheel adjusts the timer and doubles as an OK button, and last but not least there’s a back button for when you have to navigate back. Speaking of back, the backside of the device has a 1.54 inch monochrome OLED that shows the timer, the battery percentage and the Wi-Fi, Bluetooth and USB indicators. This way the device remains usable to its own user as well, even when clipped to the top edge of a monitor using its built-in mount, pointing its primary matrix display away from its user. The device measures 168.6 x 55.2 x 40.8mm and weighs 250g/8.82oz. The body is made out of PC/ABS with a PC front and back panel, and the monitor mount padding is TPE. The bar fits monitors up to 21mm thick and I can confirm that it works on curved displays as well. However, if you have a particularly thin monitor (say, one of these portable displays) it won’t be able to sit on top of it. The full specifications, as published in Flipper’s own documentation , are as follows: The 72x16 matrix is driven by the ICND2153 , a 16-channel constant-current PWM sink driver with a 16-bit grayscale shift register, LED open detection and a pre-charge circuit for ghosting reduction, and the ICN2012 8-channel power switch. One thing that is a bit sad in 2026 is the 2.4 GHz limitation for Wi-Fi. In an office environment full of devices and microwaves the bar is on the most congested spectrum available. The USB side is also kept, let’s say lightweight , with its 12 Mbit/s maximum speed, which, however, is certainly enough for a virtual ethernet interface serving a web UI and an HTTP API. On the charging side the documentation asks for an 18 W or higher PD charger for the 2.5 hour figure, while the device itself only appears to use 5V⎓3A (15 W) and 9V⎓1.5A (13.5 W) as its PD modes. There is one discrepancy with regard to the display brightness, where the tech specs page lists no brightness figure at all, the product page currently says 400 nits, and the launch coverage from CNX Software and XDA both quote 800 nits. I don’t have the equipment to measure it, so I can’t really tell which it is, but I can assure you that even in a brightly lit space it’s plenty bright. Flipper published an official disassembly guide on iFixit , which is awesome. Its 21 steps describe a device that’s designed with repairability in mind. The back cover is held by 8 clips and comes off with a plastic card. Below it are 5 Phillips PH1 screws, one on the bottom and four on the back. The battery has a press-latch connector and needs to be disconnected before anything else. The display flex cables use spudger-release latches, the main PCB is held by 3 screws, the control PCB by 5 latches, the front display back cover by 6 latches and the button stabilizer by 3 screws. The monitor mount legs are friction fits. Nothing is glued and the battery is a standard 18650 cell on a 4-pin connector, which means a replacement is easily and cheaply available from most electronics shops. For a 2026 consumer device this is probably something that my fellow Right to Repair advocates will love. The firmware sources are on GitHub as . Most first-party code is GPL, the library is MIT, graphical assets are CC-BY 4.0 and fonts are OFL 1.1, all of which are declared in a REUSE manifest. The build system is FBT , the same SCons-based Flipper Build Tool used for the Flipper Zero , and the dependency list is a usual embedded stack with FreeRTOS underneath Flipper’s own abstraction, lwIP for TCP/IP, TinyUSB for the USB device side, Mongoose as the embedded HTTP and WebSocket server, mbedTLS for TLS and LVGL for the UI. The bar also includes JerryScript in , wired up through and a service. That is the same JavaScript engine the Flipper Zero uses for its scripting apps. With the engine already in the firmware the only thing that still seems missing is the documented way to load your own scripts onto the device. The BUSY Bar runs an HTTP server and speaks the same API over three transports, documented as OpenAPI 3.1 . Plugging the device into a computer over USB brings up a virtual ethernet interface with the device at a fixed , printed on the back of the unit. is the local web interface, is the API reference generated by the firmware currently on the device, and is the base URL for said API. No authentication is used over USB, but it can be used via Wi-Fi and it must be used when going through Flipper’s cloud. This request responds with the current power status. The battery current is in mA, and both battery and USB voltage are in mV, which means that you can graph the device’s own power consumption without any extra hardware. Note: Access over Wi-Fi is disabled by default and has to be turned on from the local web interface over USB first. Once enabled, you can pick a token for authentication, which would go into an header, if you decide to set one: Access over the internet goes through Flipper’s cloud with a bearer token generated at , scoped either to a single device or to the account: Flipper maintains for Python with both a synchronous and an client. It maps method names onto API paths directly, so becomes and becomes . That makes the OpenAPI document usable as the library’s reference documentation: The library also has a module that scales and re-encodes images and audio for the device, an mDNS discovery helper for , and a firmware compatibility check. On top of that there is an official TypeScript library for all the soydevs, and a community-maintained .NET client . And there is also a Zig library, but… more on that in just a moment . :-) The BUSY Bar presents itself to Matter as a single on/off endpoint, an emulated switch with a configurable startup state of , , or . Turning it on starts the BUSY timer and turning it off ends it, making the integration is a trigger. Reporting the state back to Matter requires switching on Settings ➔ Smart home , at which point focus sessions can power automations like dimming lights or locking a door when a timer is turned on. Pairing is done using a QR code on the back screen or in the web interface, and the device can be commissioned into multiple fabrics at once. The Home Assistant integration is done through the HTTP API using the generic REST facilities, which works in both directions, meaning the device as an automation trigger, and the device as an output for anything else in the house. The BUSY Bar comes with mobile apps for your smartphones. I have tested its iOS app and, well, it was okay, I guess. I’m not a huge smartphone app user to begin with, but I’ll give my two cents here. The app basically mirrors the current state of the bar and offers rudimentary control over it. When you start a timer and you have the app set up (via Flipper’s cloud) you’ll see the app pushing a permanent notification that displays the timer on your smartphone’s lock screen. It’s also possible to configure a Do not Disturb mode that prevents other apps from interrupting your focus session whenever a timer is currently running. To me these are gimmicks, but to others these features might be worth something. Having that said, the apps aren’t rated particularly highly and while I didn’t encounter any issues during the few days that I’ve tested the iOS version, the app did leave a somewhat cheap impression by the way it looks and functions. It felt like one of these apps that corporate boomers at large hardware manufacturers would come up with, falsely believing that they are in-line with what today’s generations might want. There are a few things that bother me, however none of them are actual dealbreakers. The Wi-Fi authentication is a single shared numeric key, constrained by the API schema to , sent in a plain header over unencrypted HTTP on the local network. At the four digit minimum that is a 10,000 value keyspace, and I have found no documentation of rate limiting. The access mode enum also includes an value alongside , which means that the API can be opened on the LAN with no key at all. Hence, it’s probably a good idea to use a ten digit key and keep the device off networks you don’t control. Then there’s all the coming soon . Installing user apps, the JS SDK, the Windows application, and the expanded app library, those are all future promises. I don’t doubt the Flipper team that they will eventually arrive, but I could imagine that for a non-technical user it is probably very frustrating to have bought a device that can barely do anything at all at the moment, especially on a Windows machine. The device that arrives today is a focus timer, a clock, and a status display. Lastly, the price. It launched at USD 179 for waiting list members, then USD 199 for the first 3,000 units, with USD 249 quoted as the eventual retail price. At 249 it is a very hard sell, especially in the current software state. If you’re buying this because you’re a technical user and you really want to fiddle with it, it might be worth the Pesos, but as I’ve demonstrated in the past you can build a similar device significantly cheaper yourself, especially if you’re already deep into the tinkering rabbit hole. Flipper built the device I would have expected them to build, which I mean as a sincere compliment. The hardware is over-engineered for a status light in the same way that Flipper hardware always seems to be, with a real mechanical switch, a real encoder, a replaceable 18650, an official teardown guide and no glue anywhere in it. Whether it is worth the money depends entirely on what you intend to do with it. As a device that tells your coworkers to go away, it is way too expensive and not at all effective, because people who interrupt you are not deterred by a sign that tells them not to. Let me put it this way: For roughly $50 below the BUSY Bar ’s retail price you could place one of several Smith and Wesson models on your desk and it would likely be a more effective way to deter co-workers from talking to you. However, as a small, well-built, fully scriptable RGB matrix with an 8 GB filesystem, a WebSocket, and an elaborate priority system, so that several programs can share one screen without overwriting each other, it is the most open and probably best thing in its class, and I expect the community will find uses for it that Flipper hasn’t thought of yet. PS: Turning off the BUSY bar is like quitting Vim, in the sense that it doesn’t offer an obvious way to do so. Yes, the switch on top has an “OFF” position. However, that simply turns off the displays, but it keeps the busy bar running and connected to WiFi. If you want to fully shut down the device so that it won’t consume any battery, you will have to put the switch into the “Settings” position, navigate to System , Power , and Shutdown , and confirm the poweroff with Yes . Only then the device actually turns off. As mentioned before, I have a little bonus that I’d like to share with this review, which is a Zig library that implements the BUSY Bar ’s current OpenAPI specification as closely as possible, and that brings a command line tool that lets you control the device over its HTTP API. The library supports all of Zig’s platform targets as it only uses Zig’s library, and it is fairly lightweight and easy to use. I’m using it with my BUSY Bar and it has been working great for me. The command line tool contains a few quality-of-life features like simple commands for starting and stopping the busy mode, which would otherwise require manually writing JSON payloads. Long story short, if you’re one of the people that have ordered the BUSY Bar and are maybe looking to integrate it into Zig tools, or even just into your desktop environment using your own scripts, I invite you to check out the repository . If you’d only want the CLI tool to play around with your BUSY Bar you can find builds for every supported platform over on the release page on GitHub .

0 views
Giles's blog Yesterday

Use the built-in GELU, don't roll your own!

Unsurprisingly, PyTorch's own built-in GELU function is faster than the hand-rolled one I've been using to date. But I was surprised at how much faster using it made things when training my models. I discovered this accidentally just now while working on something unrelated, but am logging the details here for anyone else that might find it useful. The headline numbers: the same code, training the same model on the same data, ran at about: That's a 20% increase in throughput for both of the built-in versions -- definitely nothing to be sneezed at. And what is particularly interesting is that there aren't that many GELUs going on -- it's a GPT-2 small-style model, with 12 layers. So that's 12 GELUs handling tensors shaped , which is for my training setup. Given that the rest of the model is doing all of the normal full attention stuff for GPT-2, it's really surprising that the GELUs alone must have been taking up so much of the time. The throughput numbers mean that we must have been spending about 17% of our time on the extra overhead from the hand-rolled version, so that sets a lower bound for how much time the GELUs were taking up. More info below the fold. Back when I was doing the "interventions" part of my LLM from scratch series , training dozens of GPT-2 small-sized models in the cloud and on my local machines, to keep things simple I used the original model code from Raschka's book. That happens to have its own implementation of the GELU function -- you can see my copy here . I'm not that sure why the hand-rolled version is in there -- he covers the maths, but the specific implementation isn't explained in that much depth, and it seems rather like boilerplate, just a "type this in and use it" kind of thing. By contrast, for example, while he does explain the maths behind cross-entropy loss in similar detail, we use the built-in function for it rather than coding it up ourselves. When I switched to using JAX for my own from-scratch implementation , I decided to not bother porting the boilerplate, and just used JAX's own built-in version . I was revisiting the PyTorch code -- I'm in the process of extending it with mixture-of-experts support, about which more in a later post -- and decided to switch from the hand-written GELU to the PyTorch one just to tidy things up a bit. I noticed something interesting -- my new MoE code suddenly seemed to speed up. Was that a mirage? Or had I discovered part -- or even all -- of the reason why the JAX code was so much faster than the PyTorch code? With PyTorch, I was typically getting training speeds of about 21,000 tokens per second, while in JAX I was getting 24,000 tps or so. I'd been chalking that up to JAX's JIT compilation, but could it have been just a result of a random implementation choice I'd made? I did three partial test training runs, letting each one run for 20 minutes to allow the training speed to settle down from any startup overhead. Firstly, with the old hand-coded GELU: So it was getting 20,920 on average over those 257 global steps. That speed was in line with the original run of the configuration I was using. Next, I introduced the built-in PyTorch GELU with no arguments: That does the full calculations for GELU, rather than using the -based approximation that the hand-rolled code did. After 20 minutes, it looked like this: So this time we were getting 25,134 tokens per second -- 20% faster! By default, PyTorch's GELU uses an exact calculation of the function -- the hand-written code from the book uses an approximation using . Luckily, you can get that same approximation from PyTorch: So, training with that for 20 minutes: 25,142 tokens per second -- basically the same as the non-approximate version. So: switching to the built-in GELU made my PyTorch code run 20% faster, at about 25,000 tps rather than 21,000. My JAX code, which used JAX's built-in GELU, ran at around 24,000 tps. I'd actually found that rather surprising, because in JAX I was training in full-fat 32-bit floating point, while in PyTorch I was using Automatic Mixed Precision (AMP) -- a special mode that allows it to use 16-bit calculations where it won't hurt the model much. I'd found that AMP gave PyTorch a huge speedup -- from 15,402 tps to 19,797 on one test. So JAX without AMP being so much faster than PyTorch with AMP was a bit of a surprise. Its JIT is pretty amazing, but I didn't expect it to be that much faster. Now I think that we have at least part of an explanation. I was using JAX's built-in GELU (interestingly, with its default parameters, which means that it used the approximation), but the PyTorch code was using the hand-rolled one, and that unduly penalised it and erased some of the gains it got from AMP. If I really wanted to dig into this, I suppose I might try JAX with a hand-rolled GELU to see what happened. My guess is that because of its JIT, it might actually handle it better -- the whole hand-rolled thing could be compiled into one thing on the GPU. Perhaps it would also be interesting to try the non-AMP PyTorch code with the built-in GELU. But I doubt that would really be the best use of my time (and my electricity bill), so I'll leave it here. On the other hand, I do intend to have a look at in the future, to see what kind of speedup I can get from it. And it might be able to compile and fuse together the hand-rolled GELU -- so that would be an interesting thing to experiment with in that post: does the built-in GELU advantage disappear if we're compiling? But anyway, for now, lesson learned: use built-in PyTorch modules when you can. It's a pretty obvious one ;-) [Update] On X, Sebastian Raschka noted that he used the approximate version of GELU in his code so that the models were compatible with the OpenAI weights -- they were trained with that version, so they may behave slightly differently if you use the "pure" version. That's a great point, and so I've updated my own copy of the code to use . 21,000 tokens per second using the hand-rolled GELU from Sebastian Raschka 's book " Build a Large Language Model (from Scratch) ". 25,000 tokens per second using PyTorch's built-in GELU with no arguments. 25,000 tokens per second using the built-in GELU with , which uses the same maths as Raschka's version under the hood.

0 views
Farid Zakaria Yesterday

Three ways to smuggle SQLite into Nix

The core of nixpkgs-multiverse , when you strip away the Nix API and the CLI, is an index. It is a map from to the revision that shipped it as a JSON file. 1 As of 9cc0209 , is 5.3 MiB and is 7.5MiB covering 305,492 package versions across 31,904 packages and 1,534 revisions. The Nix API loads the JSON files lazily and are all read via : I would like to enrich the data with even more information however it comes at a cost: mo’data, mo’problems. The goal of the project is to minimize the number of Nixpkgs that are downloaded. If we merely swap fetching huge Nixpkgs for huge JSON, it’s not a clear win. For now we have to be judicious about what we store in the JSON files and think of clever encoding schemes to make the data small and compact. If we were not constrained to the Nix , we would leverage established technologies to efficiently encode our dataset that allow multiple query access patterns: databases! Let’s say we were not restricted to JSON, do we have any other options? Why are large JSON files so problematic? is eager . There is no lazy JSON in Nix, no streaming parse (i.e. “just give me this one key”). The moment you touch the result you have parsed all 5.3 MB and materialised all 305,492 values on the Nix heap. In the case of the multiverse, asking for one package costs the same as what asking for all of them. Note The lookup itself is not the problem. Nix attribute sets are a sorted array, so access is a binary search, not a scan. The cost is entirely in the JSON parse and in allocating the values and downloading a large file. If we want to do alternate questions over the index, we have to make sure we keep the answers efficiently stored to better match the access pattern. What we want is obvious. We want a way to efficiently encode the data and a declarative way to define queries: we want SQLite! 2 Nix by default cannot do this. Unfortunately there is no , although I think there should be… Turns out though there are knobs we can touch or sources we can patch to get what we want anyways, albeit each one has a caveat. 😈 I was surprised I did not know about this , and it has been around since release 1.11.9 in April 2017. It is the ultimate escape hatch for a variety of use-cases when you simply can’t get them done with what’s available. takes a list of strings, runs the program, and parses its stdout as a Nix expression . It is gated behind a setting that makes it clear it’s unsafe. For integration, SQLite is perfectly capable of printing the Nix syntax. We never need a serialisation format in between as we make SQLite emit the attrset directly: The caveat is that every query is now a , an , a process image of SQLite, and a re-parse of the output through the Nix parser. If you do not plan to execute many queries that overhead is likely acceptable given the simplicity of the integration. From researching , I stumbled upon . It takes a path to a shared object and a symbol name, s it, and calls that symbol. It landed in 1.8 , December 2014. 3 The shared object must implement the following signature: We can define a new native function that returns the versions for our input: The implementation is ordinary C++ using the Nix API. Below is a snippet of the implementation, making sure to cache our handles to avoid the same startup penalty as : Using it looks like this: Determinate Systems shipped a third option in March of 2026: , which calls a function inside a WebAssembly module. 4 The motivation was similar to wanting to extend Nix surface area but avoid expanding . Wasm is sandboxed and deterministic, so unlike the two builtins above, the goal is to provide a safe escape-hatch . WebAssembly is a binary instruction format for a stack-based virtual machine. The claim is that it is well suited for Nix because it has deterministic execution , which is a lot more restrained than a backdoor . A module needs to export , an initialiser called , and the entry point. Nixpkgs already includes the target for cross-compilation, so making one is pretty straightforward: You call back into the evaluator through the Nix API functions, so a wasm module builds real Nix values, similar to minus the footgun. SQLite ships an official wasm build , so the pieces seem to be sitting right there and the gears in my mind began to turn. Initial attempts to try and load a SQLite database with the traditional Nix were a bit of a failure as Nix strings cannot contain NULL bytes. Thankfully, with the help of some additional due-diligence by LLMs, we discovered that one of the Nix API functions is not in the blog post: is specifically designed for this problem. This function allows a WASM module to pull arbitrary raw-bytes off disk into its memory. Unfortunately, it’s a little too broad in that it reads the complete file which is kind of overkill and what we are trying to avoid from our initial JSON solution. In the pursuit of exploration, let’s patch the implementation and augment the API to allow random access and partial read of a file. Turns out the patch to add is relatively small and straightforward. Now we have everything we need to hook up SQLite and a custom virtual filesystem (VFS) layer to read from the provided path entry. We build a WASM target of SQLite and we set . That flag removes SQLite’s entire VFS layer and requires us to supply one. We provide the build a simple implementation of the API which is a call-back into the Nix evaluator via that newly exposed function. Everything else is stubs. Note Unfortunately gives every call a fresh instance . This is deliberate from the implementation, meaning we pay some startup code each time although not quite as drastic as a & Using it looks like this: 5 That is a real full SQLite with all the bells and whistles: prepared statement, bound parameter, b-tree descent through an index, executing inside the Nix evaluator. All through WebAssembly. 🤯 How do these four approaches compare? Here are all four approaches answering the same question: “which revisions shipped this package?” against the same 22 MB SQLite build of the index. As we initially complained, is a flat line in the wrong place. It is 0.29s whether you ask one question or two hundred, because the 5.3 MB parse happens once and dominates everything after it. starts the cheapest and climbs , roughly 3.8 ms per query of + + Nix-parsing the output. It crosses somewhere around eighty queries. is flat and nearly free , 0.05s across the whole range since we reuse SQLite instantiations across multiple invocations. The database is opened once for the entire evaluation and the pages stay warm. Unfortunately, SQLite in wasm is dominated by a fixed cost , roughly 2.5 s before the first query, then about 7 ms each query thereafter. That 2.5 s is Cranelift compiling 1.1 MB of SQLite. Right now that is a limitation of the WASM implementation however Eelco has mentioned that the generated code could be cached on disk in the future across invocations. For a lock file pinning thirty packages, still wins outright at the current index size. None of these three is right for shipping the multiverse index, and I am not going to make depend on . Asking people to run their evaluator with native code loading enabled so my flake can be faster is not a worthwhile request at the moment . For now, the index stays JSON and I’m holding back on some of the more loftier ideas I have that require a lot more data . Although philosophically I only use CppNix , I was a little intrigued and impressed with what the ecosystem could unlock with WASM. There are definitely some warts however such as waiting for it to JIT and the developer-experience of maybe having checked-in compiled blobs but there is definitely potential to unlock a variety of problems. There are actually a few other files that drive other features such as the statistics or “fast mode” , but they are all JSON as well.  ↩ nixpkgs-multiverse already exports a SQLite database as a package to help others explore this data.  ↩ The C++ field was originally called and was renamed to for .  ↩ Eelco gave a talk about this at SCALE 23x .  ↩ Don’t forget that this is needs our patched version of Determiante System’s Nix .  ↩ There are actually a few other files that drive other features such as the statistics or “fast mode” , but they are all JSON as well.  ↩ nixpkgs-multiverse already exports a SQLite database as a package to help others explore this data.  ↩ The C++ field was originally called and was renamed to for .  ↩ Eelco gave a talk about this at SCALE 23x .  ↩ Don’t forget that this is needs our patched version of Determiante System’s Nix .  ↩

0 views
Justin Duke Yesterday

Wet Hot American Summer

It feels like a long-standing embarrassment that I had never seen Wet Hot American Summer . And the longer I put it off, the harder it became to watch — like an undergrad paper already past its deadline. It wasn't even a worry that I wouldn't like it, but a sense that everything the movie had to offer I had already consumed in some other form or fashion, in the various spiritual sequels and films its stars went off to make. I was wrong, obviously, and I loved it. I loved it in much the same way I loved They Came Together , which is essentially the same film with a slightly different cast. Where They Came Together skewered rom-coms, this one makes fun of teen movies. These films are not well-reviewed in the same way a particularly good episode of Saturday Night Live in its heyday would not be well-reviewed: part of the appeal is vibes and volume. It is easy, perhaps, to focus too much on the jokes that don't land, as opposed to the ones that do. For my part, what the movie feels like is a warm hug. And in a strange way, it gives me the sense of having already watched it many times — this first viewing being the latest in an ongoing series. Not because the jokes are stale (though, having spent enough time internalizing the UCB extended universe, you could certainly make that accusation) but because it feels comfortable . Obviously it is fun to note, as many people do when discussing the film in retrospect, how many incredible stars — or if not stars, then guys — are jammed in here. But I'll avoid saying too much about them, because I don't have much to add that hasn't already been covered at length. I do want to give specific accolades to the children, who managed, in scene after scene, to just absolutely nail the assignment. This is not easy work, honestly. A version of this film in which the child actors drag down the whole thing is not far-fetched. Is this the greatest comedy movie ever? No, obviously not. But it might be the one, in some small way, that I'm most grateful for — both as a kind of beachhead for a bunch of very talented people to go on and do other things, and as a sort of rallying flag around which people can organize.

0 views

Conceptual integrity and counting lines of code

Last week I recorded an episode of the Talking Postgres podcast with Claire Giordano on the subject of "How AI is changing software development". We had a really great conversation. Here are a couple of my highlights from a lightly edited transcript (prompt to Claude: "very minor edits to remove disfluencies"). This is the latest version of an argument I've been trying to build about why sometimes it does make sense to talk about lines of code as an indicator of productivity with coding agents, at 35:01 : A lot of people will tell you it makes no sense to measure productivity in lines of code. I’d actually disagree, because there’s a hard limit. In the before-times, a software engineer could produce a few hundred lines of production-ready code per day — and 200 lines of working, debugged, production-level code is an incredibly good day. Most days you’d produce 50 or 60. If agents let you produce a thousand lines of debugged code, that really is a very meaningful improvement — as long as the code is the same quality: maintainable, tested, all of that. You can get to that point with agents, but it takes a huge amount of skill and knowledge and experience. That’s what senior engineers are made of. I can do way more work as a single engineer than I could without agents. So you could argue, why should a company have more than one engineer? Beyond the obvious bus factor thing — a team of one is a very badly designed team — the answer is that the new limiting factor is cognitive capacity. I can churn out code a hundred times faster. I don’t have the cognitive capacity to stay on top of 100 times the amount of code. So you still need a team of engineers, so you can load balance that cognitive capacity across the team. And this section on conceptual integrity at 46:03 , which Claire equated to the Winchester Mystery House ! Simon : There’s a concept in The Mythical Man-Month — conceptual integrity — where well-designed software has an integrity to it: there are no surprises in it, it covers exactly the right domain of things, everything fits together and makes sense. That’s so much harder with coding agents, where you can have an idea for a feature, run a prompt, and five minuteslater you’ve got the feature. Your software grows little weird bumps in funny different directions. Claire : You know my analogy for that? The Winchester Mystery House. Simon : It’s got 140 rooms, because the woman who built it was the widow of the guy who invented the Winchester rifle, and her psychic told her she’d be haunted by the ghosts of everyone killed with that rifle unless she kept building the house forever. So for 40 years she kept adding new rooms. That’s exactly the problem with coding agents and software: it’s very easy to keep adding new rooms, because the cost of adding those rooms is so much cheaper. What you end up with is something where the conceptual integrity falls apart — and then it’s harder to make decisions about it. It all keeps coming back to discipline. It used to be that the discipline was enforced on you by the amount of time it took. You’d come up with an idea for a crazy feature and think “yeah, but that would take me a week — I cannot justify that, so I’ll forget about it.” If it takes an hour, it’s so much easier to justify. (Side-note: the Wikipedia article includes credible sources that dispute the story about the psychic.) You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options .

0 views
Martin Fowler 2 days ago

Citizens Build, Agents Execute, Experts Govern

TL;DR Why building an app over the weekend isn't the same as building enterprise software I’ve noticed an interesting gap opening up over the last six months. It isn’t really a gap in technology. It’s a gap in what different people think software engineering actually is. The conversation usually starts the same way. A non-techie, maybe an executive, tells me about something they’ve built over the weekend. Sometimes it’s a chatbot. Sometimes it’s an internal workflow. Sometimes it’s a surprisingly polished application that solves a real business problem. They’re excited, and they should be. Twelve months ago they probably couldn’t have built it at all. Then comes the question. “If AI can do this now, why aren’t our engineering teams delivering ten times faster?” It’s a perfectly reasonable question, after all we’ve all seen the demos. The first thing that would come to my head is “you don’t know what it takes to build enterprise grade software”. But then I think about what I mean and how to explain it to a non-technical person without sounding super patronising. And then it hit me, we did this to ourselves. We’ve spent so many years banging on about how to write good software that everyone has assumed writing software is the same as software engineering. The application someone builds over the weekend is real software. It likely solves a real problem or demonstrates an idea. Sometimes it’s genuinely impressive. I don’t want to diminish that because I think one of the most exciting things AI has done is dramatically increase the number of people who can turn ideas into working software. That’s cool, I totally get it. The first apps and “hello worlds” I ever built excited me enough to choose this as an actual career so the excitement is real and I don’t want to temper it too much. But your first hello world, which these days can be an entire app with all kinds of features, is very, very (extra very on purpose) different from introducing software into a production environment in a highly regulated enterprise, as an example. But why? The moment that application becomes something the business depends on, the questions change completely. Is customer data protected? What happens when a dependency fails? Can someone else understand this system in two years’ time? Will it survive an audit? Can it cope with a thousand times more users than it has today, what about millions in one day? How will we know something is wrong before our customers do? Those questions don’t show up in a demo or in the build phase at all unless an experienced engineer is in the room. I certainly wasn’t asking them when I was building my first apps. I only cared about features! This is where experienced engineers become more important, not less. Not because they’re the only people who can build the software anymore, but because they have the judgement to know whether we can trust it: whether the design is good, the risks are understood, and the thing that works today won’t become somebody else’s nightmare six months from now. At FOSE a few weeks ago, we spent surprisingly little time talking about coding. We talked about whether code was still the source of truth, and occasionally about how much we missed writing it, but mostly we talked about design, architecture, governance, learning and judgement. One team described spending the day designing a specification, letting agents work overnight and reviewing the results the next morning. The interesting bit for me wasn’t the overnight pipeline, cool as that was. It was what the humans were doing: deciding what good looked like, making trade-offs and judging whether what came back was actually what they wanted. We also kept coming back to good design, because it turns out that when agents can generate lots of code very quickly, good design matters more, not less. That made me wonder whether we’ve been thinking about scarcity in the wrong way. We’ve spent decades optimising around people who can write code because they were scarce and expensive. I’m not convinced that was ever the real scarcity, but that’s probably another ramble. What feels scarce now is good engineering judgement: knowing what good looks like, understanding the risks and knowing when something that works is actually safe to trust in production. Because software doesn’t exist to be built. It exists to run in production and safely solve the problem it was created for. Organisations don’t run on code. They run on trust. A few months ago I found myself saying something in a conversation almost without thinking. Citizens build. Agents execute. Experts govern. It sounded cool and I thought marketing would like it, so I wrote it down. Then I left it alone for a while. The funny thing about writing these ramblings is that I don’t know whether I believe something until I’ve let it bounce around in my head for a while and also said it to other people I trust like senior engineers at Thoughtworks. Sometimes I come back convinced I was talking nonsense. Occasionally I realise there was something more interesting hiding underneath. This was one of those occasions where the latter was true. At first I thought I was talking about roles. Citizens build software (essentially non-engineers). Agents write the code. Engineers become governors. But I don’t actually think that’s what I meant. I think I was talking about where value is moving. AI has given everyone a new way to express their ideas. The execution is increasingly handled by agents. They write the code, refactor it, generate tests, fix bugs and iterate at a speed that simply wasn’t possible before. But neither of those things reduces the need for expertise. In fact, I think it does exactly the opposite. When everyone can create software, somebody still has to decide whether that software deserves to exist inside an enterprise system in PRODUCTION. Somebody still has to think about architecture. Security. Resilience. Operability. Compliance. Cost. The boring stuff that nobody gets excited about in a demo but that becomes painfully important the first time a customer can’t log in or an auditor comes knocking. That’s why I don’t think experienced engineers become less important. I think they become dramatically more leveraged. Their job shifts from building every feature themselves to creating the environment in which thousands of features can be built safely by other people and by agents. They become the people who design the guardrails, the platforms, the engineering practices and the feedback loops that allow everyone else to move quickly without creating chaos. Perhaps that’s the future software organisation. Not one where everyone becomes a software engineer. Not one where software engineers disappear. One where almost anyone can create software, agents increasingly execute it, and engineering expertise becomes the thing that allows all of that creativity to scale safely. And to be clear I do not mean people build stuff and throw it to engineers to fix, that is a total antipattern for another ramble. Perhaps that’s why the executives and engineers I’ve been speaking to sometimes sound as though they’re describing completely different futures. The executive sees that anyone can now build software. The engineer sees that somebody still has to live with it. Both are right. They’re simply looking at different parts of the same system we have to solve to create whatever the future actually ends up being.

0 views
Martin Fowler 2 days ago

Practitioner Voice: The Writing Category Nobody has Named Yet

Jim Highsmith recognizes that effective writing from a practitioner is a style distinct from academic writing or thought-leadership content. It's a style that I advocate, and my contributors mostly follow. Jim decided it was important to give it a name, and identify what makes it distinctive.

0 views