Reading List
The most recent articles from a list of feeds I subscribe to.
Zig's anti-LLM contribution policy
As shared by on Simon Willison’s blog, Zig has an interesting anti-LLM policy for contributions in their code of conduct.
Zig values contributors over their contributions. Each contributor represents an investment by the Zig core team - the primary goal of reviewing and accepting PRs isn’t to land new code, it’s to help grow new contributors who can become trusted and prolific over time.
I don’t think an anti-LLM policy makes sense for most projects. But a programming language requires considerate intent and deep knowledge for changes. It’s an interesting fit there.
In addition:
If a PR was mostly written by an LLM, why should a project maintainer spend time reviewing and discussing that PR as opposed to firing up their own LLM to solve the same problem?
We’ve historically preferred PR contributions over issues, because it puts the contributor in the position to do most of the work. But if a PR is just a contributor prompting an LLM, is a well-written issue preferable? When writing code becomes cheaper, might as well let the maintainer get it done using their taste.
Time for lower level languages?
I’ve always been intrigued by Go. It’s powerful, fast (I really like fast), and simple. The tradeoff? It’s simple. Coming from higher level languages like PHP & JavaScript, Go can feel crude.
As I’ve recently written, this blog went back to Hugo. Hugo is also fast and crude. But with LLMs, the crudeness of things doesn’t hurt as much as before. I don’t need to deal with writing it anymore, and crude is still readable.
From Just Fucking Use Go:
The boring choice is the right choice. It always was.
I agree. More than ever, I have an urge to dabble into lower level languages. AI is a huge layer of complexity we’re adding to our tooling. Let’s use it to trim the fat from our outputs.
Sanding UI
This is an older post from Jim Nielsen on building user interfaces I came back to last week.
With software, the fact is that sometimes there are just too many variables to know and test and smooth out. So I click around, using the UI over and over, until I finally cannot give myself any more splinters.
I feel this. I’m better at my job when I’m actually using something. Even better when I’m using something because I want to use it.
I’ve been building a side project on and off for a few months now. Having it my phone’s homescreen and actually using it every day gives me a different perspective on it than just building it and shipping it to others, like is often the case for client work.
Sand it, feel the grain, get a splinter, sand again, and repeat until smooth.
Introducing Piper: a pipe operator-first PHP utility library
When I experimented with Elixir a few years ago, I fell in love with the pipe operator |>. Since then, I’ve always dreamt of a similar tool in PHP.
Last year, we finally got it! Unfortunately, the standard array & string manipulation functions in PHP aren’t exactly known for their API consistency, which makes the pipe operator awkward to use.
I ported Laravel’s excellent collection & string helpers to a pipe operator-optimized API. Piper is an attempt to wrap the standard library to make it compatible with the pipe operator.
use function Spatie\Piper\Arr\{filter, join, map};
use function Spatie\Piper\Str\{prefix, suffix};
[1, 2, 3, 4, 5, 6]
|> filter(fn (int $i) => $i % 2 === 0)
|> map(fn (int $i) => pow($i, 2))
|> join(', ', ', and ')
|> prefix('The winning numbers are ')
|> suffix('.');
// "The winning numbers are 4, 16, and 36."
I wrote a technical introduction to the package on the Spatie blog. Documentation can be referenced here, and the repository is hosted on GitHub.
The sad part (maybe?)
I’ve never seen a coding agent return code using a pipe operator unless I’ve explicitly asked it to. That makes sense: the models we use are trained on years of historical data, and the pipe operator is a fairly new feature.
I might never use this library. I might never use the pipe operator at all. Agentic coding is pushing syntax to a standstill. New programming APIs that bring benefits to execution will be pushed forward. But the whole fight for making code look good seems to have been extinguished as AI is slowly moving us to focus on outcomes more than line-by-line code cleanliness. That’s not necessarily a bad thing, but part of our craft might get lost along the way.
Ironically, I convinced myself to actually write this because I have AI at my disposal. Manually porting 234 functions and a full test suite is not something I was looking forward to. Instead, the time spent building and refining this package is measurable in hours.
Either way, this is a fun experiment to conduct. And I look forward to tinkering further and giving it a shot in some real projects.
Back to hugo
This blog has gone through a few technical iterations. Most recently: from a Laravel app with Sheets, to a static site with Hugo, to a CMS-driven site with Statamic. And now, back to Hugo!
I love Hugo. It’s purposefully built with the right abstractions, and incredibly fast. The kind of fast that makes you wonder why other software can be that fast. Fast software, the best software. But the templating language… it might be an acquired taste, but I never acquired it. Updating my theme or adding a custom page was always a chore. I got tired of it. Coincidentally, I wanted to experiment with more dynamic workflows on here (posting to social media, more control over scheduling…) so I migrated to Statamic (a lovely CMS!)
Fast forward three years and a blogging hiatus, and I started to crave the simplicity of the good old static site. Having a dynamic system was fun, but it requires maintenance and having it made me realize I didn’t need it. Add to that we’ve commoditized robots building things for us, and switching back to Hugo was the right move. A single prompt and 15 minutes later, my entire blog was translated from Statamic to Hugo. The best part: I don’t need to care about the templates anymore. Sure, I’ll dive in occasionally for some surgical styling tweaks. But generally, changes are handled with a quick prompt.
GitHub pings my webserver to auto-deploy on push. Scheduling is solved by running the deploy script every hour. As a static site, everything’s fast by default and there are almost no points of failure. Life is simple. All that remains is to write!