More from Paolo Amoroso's Journal
<![CDATA[I initially used Linux from the mid 1990s to 2015, first as dual boot with Windows 95 and then as my only desktop operating system. Back then my PC had an Nvidia graphics card and system updates frequently broke X11 on Linux, leaving me at the text console with no idea what to do. At some point I stopped applying the updates as I dreaded change. In 2015 I had enough and switched to ChromeOS. Although I still used Crostini Linux on ChromeOS, over the years I increasingly bumped into the limitations of this containerized approach. The rumors of Google considering for ChromeOS a feature like Windows Recall eventually made the cloud operating system a deal breaker. So I decided to migrate back to Linux for good, bought a System76 Merkaat mini PC with no Nvidia hardware, and installed Linux Mint Cinnamon. It's been seven months since my switch back to Linux in July of 2024 and, despite some early issues, my experience with Mint has been smooth and uneventful. Linux supports all my hardware, system updates install seamlessly, and everything works. The system fades into the background and I can focus on running the programs I need. In my early Linux years I often upgraded to every major and minor version of my distro. There were good reasons as Linux evolved rapidly, significant features came out regularly, online updates weren't a thing, and getting online was costly and impractical. It helped that I was younger and eager to play with Linux. In January of 2025 Linux Mint 22.1 was released, the first minor version since my current Mint 22. But this time I'll defer upgrading until at least the next major release, or possibly for a year or two. I feel no pressure as system updates flow regularly over the support period of Mint 22 that ends in 2029. Besides, upgrading involves some preparation and work I don't look forard to doing. If some features I really want do come out I may consider upgrading. But, for now, I want to savor this newfound Linux stability. Linux has really come a long way. Linux a href="https://remark.as/p/journal.paoloamoroso.com/enjoying-the-stability-of-linux"Discuss.../a Email | Reply @amoroso@fosstodon.org !--emailsub--]]>
<![CDATA[It's a joy to use the Cardputer uLisp Machine, a nice little microcontroller system that runs uLisp. But after a short experience I had to put aside my Cardputer due to a showstopper issue that made it impractical to program the device. Since then a good workaround emerged and I learned how to improve the experience with the device. The showstopper is a buffer overflow when sending Lisp code from Emacs to the Cardputer over a serial USB line. If the receive buffer fills up too fast the device will crash and disconnect. Sending more than a few hundred bytes triggers the issue and makes it impractical to evaluate medium or large code blocks. This acknowledged Arduino issue reported in February of 2022 has not been addressed yet. Meanwhile, Dennis Draheim devised a workaround. He wrote some Emacs Lisp code to open a serial connection to the Cardputer and send an expressions or region for evaluation. The trick is to split the input into lines and send one line at a time, with a delay in between to keep the Cardputer's serial buffer from overflowing. Dennis' code works well and makes uLisp usable on the Cardputer. The only downside is the echoed input clutters the Emacs serial buffer. Our attempts at turning off echo failed as we don't know where Emacs handles this. The workaround enables running more substantial and interesting uLisp programs such as this nice surface of rotation graphics demo: 3D function plot on the display of a Cardputer uLisp Machine device. The Cardputer has a tiny built-in keyboard that is handy for short interactions. But it's prone to overtyping when entering a character that requires pressing two keys, such as shifted characters or the parentheses. I originally attempted to press at the same time the Aa shift key and the key with the desired symbol. But this often results in typing more than one character as hitting such tiny targets simultaneously is difficult. I later stumbled upon a way to consistently avoid overtyping: I press and hold Aa, then press the key with the desired character. #Cardputer #Lisp a href="https://remark.as/p/journal.paoloamoroso.com/making-ulisp-more-usable-on-the-cardputer"Discuss.../a Email | Reply @amoroso@fosstodon.org !--emailsub--]]>
<![CDATA[In 2023 I migrated my personal website from Squarespace to Blot. Blot is a static site generator that publishes as a website a folder stored on Google Drive, Dropbox, or a Git repository. Back then I set up Blot to publish a Google Drive folder but I recently switched the synchronization to a Git repository. It was necessary as Blot has been unable to access Google Drive since Google eventually imposed onerous and expensive auditing processes to use their API. This forced Blot and other small developers to drop support for Google Drive. Blot's developer is implementing a workaround that will allow to continue using Google Drive. But I decided to go with Git anyway as it's a better fit for my current tools and workflows. Switching to Git instantaneously and seamlessly created a repository I can clone and update to change the site. #blogging #Google a href="https://remark.as/p/journal.paoloamoroso.com/switching-blot-sync-from-google-drive-to-git"Discuss.../a Email | Reply @amoroso@fosstodon.org !--emailsub--]]>
<![CDATA[MattoF has tagged me for the Blog Question Challenge which asks bloggers questions about their background and motivations, tools, and workflows. It is a variation by Kev Quirk of a challenge originally created by Ava at Bear Blog. I have accepted this fun challenge and this is my entry. Why did you start blogging in the first place? I started in 2004 in the golden era of blogging. I enjoyed blogs and their community, wanted to experiment with the new medium and tools, and thought I had something to say. So I set up a blog to tap into and amplify this energy. What platform are you using to manage your blog, and why do you use it? For my blog Paolo Amoroso's Journal I use Write.as because it's a lightweight blogging platform with a clean design and excellent support for technical writing, which is what I mostly do. As a byproduct these features reduce friction in writing and publishing. I settled on Write.as after a long journey across blogging platforms. Have you blogged on other platforms before? Yes, and I used static site generators well before it was cool. My first platform was BlogMax, an Emacs package we would now describe as a static site generator. Back then I was a heavy Emacs user and it seemed natural to blog with Emacs. My first blog has been online since I started it in August of 2004, now an abandoned time capsule of what its name unambiguously hints has always been my obsessionpassion: Lisp Propulsion Laboratory log. For my blogs I later used Blogger, Micro.blog, and eventually Write.as. I also used the elephant in the room, WordPress, for contributing to other blogs. How do you write your posts? I just use the online Markdown editor of Write.as as I don't need anything fancier. When do you feel most inspired to write? I mostly do technical writing and my blog is a sort of lab log. It's usually clear what to write about and inspiration is rarely involved. In general I write when I complete a project, am stuck with a technical issue, or I just want to record the progress and experience with a project or something I do. Do you normally publish immediately after writing, or do you let it simmer a bit? I never publish immediately. I'm a slow writer and do lots of editing rounds, especially as a non native English speaker. Letting it simmer improves the final result. What’s your favorite post on your blog? My favorite is My encounter with Medley Interlisp, which captured my exhilaration at approaching and exploring Medley Interlisp. I was beginning to dive deep into this 1980s Lisp workstation environment I had always dreamed of, and blogging the experience seemd a natural way of sharing my excitement and explaining what's unique about Medley. This is apparently also the favorite post of my readers. It's the most visited of the blog and received over 38K views, most of which when it was shared on Hacker News. Any future plans for the blog? No, which is a feature. Everything is going so smoothly I just want to continue blogging without worrying about tools and platforms. Who's next? I nominate Fabrizio Ferri Benedetti, Kevin Tofel, and Rob Roland. I hope they will accept as they have interesting blogs and diverse stories. blogging a href="https://remark.as/p/journal.paoloamoroso.com/i-accepted-the-blog-question-challenge"Discuss.../a Email | Reply @amoroso@fosstodon.org !--emailsub--]]>
More in programming
Last year I wrote about inlining just the fast path of Lemire’s algorithm for nearly-divisionless unbiased bounded random numbers. The idea was to reduce code bloat by eliminating lots of copies of the random number generator in the rarely-executed slow paths. However a simple split prevented the compiler from being able to optimize cases like pcg32_rand(1 << n), so a lot of the blog post was toying around with ways to mitigate this problem. On Monday while procrastinating a different blog post, I realised that it’s possible to do better: there’s a more general optimization which gives us the 1 << n special case for free. nearly divisionless Lemire’s algorithm has about 4 neat tricks: use multiplication instead of division to reduce the output of a random number generator modulo some limit eliminate the bias in (1) by (counterintuitively) looking at the lower digits fun modular arithmetic to calculate the reject threshold for (2) arrange the reject tests to avoid the slow division in (3) in most cases The nearly-divisionless logic in (4) leads to two copies of the random number generator, in the fast path and the slow path. Generally speaking, compilers don’t try do deduplicate code that was written by the programmer, so they can’t simplify the nearly-divisionless algorithm very much when the limit is constant. constantly divisionless Two points occurred to me: when the limit is constant, the reject threshold (3) can be calculated at compile time when the division is free, there’s no need to avoid it using (4) These observations suggested that when the limit is constant, the function for random numbers less than a limit should be written: static inline uint32_t pcg32_rand_const(pcg32_t *rng, uint32_t limit) { uint32_t reject = -limit % limit; uint64_t sample; do sample = (uint64_t)pcg32_random(rng) * (uint64_t)limit); while ((uint32_t)(sample) < reject); return ((uint32_t)(sample >> 32)); } This has only one call to pcg32_random(), saving space as I wanted, and the compiler is able to eliminate the loop automatically when the limit is a power of two. The loop is smaller than a call to an out-of-line slow path function, so it’s better all round than the code I wrote last year. algorithm selection As before it’s possible to automatically choose the constantly-divisionless or nearly-divisionless algorithms depending on whether the limit is a compile-time constant or run-time variable, using arcane C tricks or GNU C __builtin_constant_p(). I have been idly wondering how to do something similar in other languages. Rust isn’t very keen on automatic specialization, but it has a reasonable alternative. The thing to avoid is passing a runtime variable to the constantly-divisionless algorithm, because then it becomes never-divisionless. Rust has a much richer notion of compile-time constants than C, so it’s possible to write a method like the follwing, which can’t be misused: pub fn upto<const LIMIT: u32>(&mut self) -> u32 { let reject = LIMIT.wrapping_neg().wrapping_rem(LIMIT); loop { let (lo, hi) = self.get_u32().embiggening_mul(LIMIT); if lo < reject { continue; } else { return hi; } } } assert!(rng.upto::<42>() < 42); (embiggening_mul is my stable replacement for the unstable widening_mul API.) This is a nugatory optimization, but there are more interesting cases where it makes sense to choose a different implementation for constant or variable arguments – that it, the constant case isn’t simply a constant-folded or partially-evaluated version of the variable case. Regular expressions might be lex-style or pcre-style, for example. It’s a curious question of language design whether it should be possible to write a library that provides a uniform API that automatically chooses constant or variable implementations, or whether the user of the library must make the choice explicit. Maybe I should learn some Zig to see how its comptime works.
A few months ago I wrote about what it means to stay gold — to hold on to the best parts of ourselves, our communities, and the American Dream itself. But staying gold isn’t passive. It takes work. It takes action. It takes hard conversations that ask
Bean counters have a bad rep for a reason. And it’s not because paying attention to the numbers is inherently unreasonable. It’s because weighing everything exclusively by its quantifiable properties is an impoverished way to view business (and the world!). Nobody presents this caricature better than the MBA types who think you can manage a business entirely in the abstract realm of "products," "markets," "resources," and "deliverables." To hell with that. The death of all that makes for a breakout product or service happens when the generic lingo of management theory takes over. This is why founder-led operations often keep an edge. Because when there’s someone at the top who actually gives a damn about cars, watches, bags, software, or whatever the hell the company makes, it shows up in a million value judgments that can’t be quantified neatly on a spreadsheet. Now, I love a beautiful spreadsheet that shows expanding margins, healthy profits, and customer growth as much as any business owner. But much of the time, those figures are derivatives of doing all the stuff that you can’t compute and that won’t quantify. But this isn’t just about running a better business by betting on unquantifiable elements that you can’t prove but still believe matter. It’s also about the fact that doing so is simply more fun! It’s more congruent. It’s vibe management. And no business owner should ever apologize for having fun, following their instincts, or trusting that the numbers will eventually show that doing the right thing, the beautiful thing, the poetic thing is going to pay off somehow. In this life or the next. Of course, you’ve got to get the basics right. Make more than you spend. Don’t get out over your skis. But once there’s a bit of margin, you owe it to yourself to lean on that cushion and lead the business primarily on the basis of good vibes and a long vision.