Quick bits
-
I’ve got a birthday picnic coming Sunday. If we’re mutuals and I by chance haven’t invited you yet, poke me and I’ll send you the invitation. It’d be lovely to see you.
-
The stress for moving is building. In just under three weeks, I’ll be out of my apartment in Berlin, though not quite in London just yet.
-
I’ve noticed that there are people who will pick up stuff that I give away for free on Kleinanzeigen, and then immediately put it back up on the classifieds platform themselves — for sale. Clearly, such items are more valuable to them than to me, but it feels dishonest and slightly exploitative.
-
YNAB not supporting multiple currencies is quite a pain. Perhaps some time I’ll revive my budgeting software project idea.
-
The platform you use to log in to Belgian government services is called CSAM. Ouch. And here I was thinking that Germany’s
BDSMBMDS1 was bad naming.
Tech bits:
-
One annoying aspect of
git diffwas thea/and/bprefixes, but this week I discovered a way to turn it off:git config --global diff.noprefix true— neat! -
I wrote a macOS dark mode switcher script because it really feels like something you can automate. I’ve linked it up to Alfred for convenience.
Zig String abstraction
My finance tooling deals with a ton of strings — payees, memos, account names, and more — that travel through a tokenizer, a parser, and more. To simplify the memory management for these strings, I came up with a String abstraction in Zig:
const name_borrowed: String =
.initBorrowed("Denis");
const name_owned: String =
.initOwned(
allocator,
allocator.dupe(u8, "Denis"),
);
The two variants, borrowed and owned, differ in their deinit() behavior:
// nothing is deallocation here:
name_borrowed.deinit();
// contents are deallocated here:
name_owned.deinit();
The String type itself is just a slice and an optional allocator:
bytes: []const u8,
allocator: ?std.mem.Allocator,
The purpose of this abstraction is threefold:
- correctness (I): don’t reuse freed memory
- correctness (II): don’t leak memory
- efficiency: don’t copy bytes just to avoid deallocation
I also have claim(), which transfers ownership. In other words, it removes the allocator from the String and moves it onto a new String:
// before:
// - name_owned.allocator is set
const name_claimed = name_owned.claim();
// after:
// - name_claimed.allocator is set
// - name_owned.allocator is NOT set
When calling claim() on a borrowed String, it will create a copy. I’m not sure how I feel about that: do I perhaps need claimOrCopy() and claimOrBorrow() separately?
There is also the borrow() function which creates a borrowed version of a string, but I don’t find it particularly useful: most of the time, you can just pass the []const u8.
This String class has been particularly useful when writing test cases. Previously, my data structures would own their string properties, which meant creating copies of every string before instantiating a struct from them. Now it’s cleaner, with no more copying needed:
test "xxx" {
const me: Person = .{
.name = .initBorrowed("Denis Defreyne"),
};
// ...
}
I am still early in the process of using it, but so far it has been quite useful.
Am I reinventing the wheel here? Probably! These are smart pointers, after all, in a way. Reference counting would’ve been a valid alternative, but much more heavyweight.
Inevitably the question comes up whether I could’ve used an arena here. I don’t think that would quite work: I want to be able to deallocate strings I no longer need, but also retain strings that I do need, long-term, without having to think about which arena to allocate it into.
In any case, I’m sure I’ll have more to say at some point later when I’ve used more of this.
Entertainment
- I am playing Kingdom Come: Deliverance2 so slowly that I’m barely making progress. On multiple occasions, I’ve forgotten some of the controls… which is a problem when you suddenly forget how to block in a sword fight. I’m still having fun, though!
Links
-
Photographer Spends Night on Freezing Mountain to Capture Rare Triple Galaxy Arch (PetaPixel): Wow!
-
FAR RIGHT THREATS: Useful to know.
-
TBM 383: Maximizers vs. Focusers (John Cutler): I’m much more of a focuser myself, though I imagine that’s not much of a surprise.
-
Lena Richter on Wero privacy (in German): Oof. I have not used Wero myself, but being able to see someone’s legal name just from their phone number sure is a major privacy violation.
-
Cat Doesn’t Want Dog Or lamb On his Rock (Lee Walters): Aww!
-
maybe I'm the alien (exurb1a)
Tech links:
-
Multi-stroke text effect in CSS (Yuan Chuan): Ooh, so pretty!
-
Reminder: You Can Stitch Together Lots of Little HTML Pages With Navigations For Interactions (Jim Nielsen): The menu-as-a-separate-page trick is neat — even though I’m not convinced that it is all that useful.
-
taken.: I’m not surprised at the amount of detail browsers give away.
-
GNU Recutils (James Tomasino): I had not heard of recutils before! This seems like it belongs in my toolbox.
-
Tiny Lua Compiler (TLC): Ooh, this looks great!