Weeknotes 2025 W22: AppKit satisfaction
Quick bits:
-
Thursday was a public holiday, and I took Friday off too.
May has had quite the number of public holidays: the 1st, the 8th, and the 29th — all on Thursdays. One more public holiday in June, then nothing until October.
-
I repotted a few plants that were becoming root-bound and whose root systems weren’t doing so well (with root rot, ouch). I’ll have to see how well they do from now; I fear some of them can’t be saved.
Tired of needing a review for your pull requests at work? I’ve got a solution!
-
Pick a random PR that is (a) not yours, and (b) not merged.1
-
Force-push your branch to this PR.
-
Approve “your” PR. (This works because this PR is technically not yours.)
-
Merge it!
Easy!2
I’ve been making good progress on Deniki. Among other enhancements, it now has syntax highlighting and a Settings window for configuring the font and the line height:

I am beginning to understand AppKit from a conceptual and philosophical point of view. Even though it’s an old framework,3 it is remarkably well-designed.
That said, there are two things that severely bother me:
-
The documentation is atrocious. The current version of the document is extraordinarily sparse, but luckily the documentation archives are still around. The archived documentation is extensive and still relevant, though often you’d need to translate it to modern AppKit and modern Swift.
-
State management is a pain. Views don’t automatically update when models change; you need to write the glue code for that. This is especially painful when coming from something like React, where views and models are intrinsically linked.
Overall, though, working with AppKit is remarkably satisfying, and I’m happy to have been able to build an application like this.
I am glad that I am not bothering with SwiftUI this time around. SwiftUI is convenient, but woefully underpowered: in my experience, straying from the narrow well-trodden path means you’ll find yourself in AppKit by necessity anyway.
It is great to be using Deniki to develop Deniki. It is the minimalist yet flexible project-management software I did not know I needed. The wiki for Deniki has the to-do list, a wish list, the list of bugs, the release notes, and a tech debt page.
Worth noting that the Deniki project is separate from my idea of creating a structured prose editor. There is some overlap, but the two are separate projects. The prose editor is on hold for now, but I want to pick it up again later — after I finish Deniki.
Learning new programming languages or frameworks (like Swift and AppKit) is far from straightforward. At the recommendation of others, I played around with code-generation LLMs to help me out.
I used Google Gemini to get me going with solutions to specific problems I had. At first, I felt that it was genuinely helpful: it gave me insights that enabled me to proceed.
But since learning more about Swift and AppKit from various sources, generative AI for code generation have turned out to be not helpful. The code that Google Gemini spat out was sub-optimal most of the time, if not straight-up wrong. The hints and guidance I’ve been getting from it are misleading, the code badly designed, with methods and classes and constants that don’t exist (and have never existed), and with solutions that are so convoluted and ineffective to be barely usable.
Of all the uses of generative AI, I’ve been the least skeptical of code generation. Yet here I am, having essentially not used a single line of code that came out of Google Gemini. None of it is good. Some of it is adequate, but still necessitated a rewrite.
I am not surprised. Code-generation LLMs like Gemini and GitHub Copilot are trained on a public corpus of code with a broad spectrum of quality: vast swaths of publicly accessible code are incorrect, out of date, incomplete, inefficient, or badly written in one of myriad other ways.
Not to mention that LLMs train on output generated by other LLMs, too. This is a disaster waiting to happen.
And of course, LLMs spit out code that is trained4 on other people’s copyrighted material. Google Gemini has produced code that is virtually identical to copyrighted code I found elsewhere, and gave no attribution.5
My experience with using LLMs for code generation, which has now come to a disappointing end, leaves me with a giant question: how in the world can “vibe coding” ever be a sustainable practice? It is more clear than ever to me that relying on generative AI for software engineering is a dead end.
Entertainment:
- Queer6 was excellent, and now I want to watch everything else that Luca Guadagnino and Justin Kuritzkes have made, and sink my teeth in some William S. Burroughs as well.
Links:
-
My (Expensive) Lesson In Failure (Venus Theory)
-
Owls in Towels: Aww!
-
What’s wrong with American aviation? (Good Work)
-
It can be a closed (but un-merged) PR, too! Just reopen it before you push. ↩︎
-
I guess you could technically disallow this by creating a GitHub ruleset with “Dismiss stale pull request approvals when new commits are pushed” and “Require approval of the most recent reviewable push” enabled, but that sounds terribly boring and unproductive. ↩︎
-
Dating back to the ’90s! Maybe even the ’80s? ↩︎
-
Illegally, in my opinion, though that is up for courts to decide sooner or later. ↩︎
-
Google Gemini does provide sources, but these sources are often bizarrely irrelevant to what was generated. Most of the times, though, there are no citations, even when it is blindingly obvious where the content originated. ↩︎
-
Queer, directed by Luca Guadagnino, written by William S. Burroughs and Justin Kuritzkes (The Apartment, Frenesy Film Company, FremantleMedia North America, 2024). ↩︎