METR just released another report, titled “Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity.” The pull quote is: Surprisingly, we find that when developers use AI tools, they take 19% longer than without—AI makes them slower. I’ve been pondering this one all morning. I generally like their methodology. Obviously you always want ever-more controlled experiments slicing every possible input, but as a real-world trial, the experimental design I thin...| cocoaphony.micro.blog
I use AI a lot for work, pretty much all day every day. I use coding assistants and custom agents I’ve built. I use AI to help code review changes, dig into bugs, and keep track of my projects. I’ve found lots of things it’s very helpful with, and lots of things it’s terrible at. If there’s one thing I have definitely learned: it does not work the way I imagined. And the more folks I talk with about it, the more I find it doesn’t work like they imagine, either.| cocoaphony.micro.blog
I use AI a lot for work, pretty much all day every day. I use coding assistants and custom agents I’ve built. I use AI to help code review changes, dig into bugs, and keep track of my projects. I’ve found lots of things it’s very helpful with, and lots of things it’s terrible at. If there’s one thing I have definitely learned: it does not work the way I imagined. And the more folks I talk with about it, the more I find it doesn’t work like they imagine, either.| cocoaphony.micro.blog
I use AI a lot for work, pretty much all day every day. I use coding assistants and custom agents I’ve built. I use AI to help code review changes, dig into bugs, and keep track of my projects. I’ve found lots of things it’s very helpful with, and lots of things it’s terrible at. If there’s one thing I have definitely learned: it does not work the way I imagined.| cocoaphony.micro.blog
I feel there’s definitely a blog post in here. I don’t want to get distracted from my testing series, but my head’s just churning and I need to write stuff, so maybe I’ll just sketch a story until I can turn it into something more coherent. I’ve been working on this small program to convert close-scored choral music into separate rehearsal tracks. I currently do it by hand in MuseScore, but…come on. I’m a programmer. I build stuff. But really I wouldn’t build this. It’s too ...| Rob Napier
Following up on some discussion about why I keep finding myself using Mutex (née OSAllocatedUnfairLock) rather than actors. This is kind of slapped together; eventually I may try to write up a proper blog post, but I wanted to capture it. Each of these is a runnable file using swift ..., with embedded commentary. // Actor to manage deferring execution on a bunch of things until requested // Seems a very nice use for an actor.| cocoaphony.micro.blog
Swift concurrency has a feature called for-await that can iterate over an AsyncSequence. Combine has a .values property that can turn Publishers into an AsyncSequence. This feels like a perfect match! But it is surprisingly subtle and makes it very easy to drop messages if you’re not careful. Consider the following example (full code is at the end). // A NotificationCenter publisher that emits Int as the object. // (Yes, this is an abuse of `object`. Hush. I'm making the example simpler.) l...| Rob Napier
I have a very simple type in my system. It’s just an immutable struct: public struct AssetClass: Sendable, Equatable, Hashable, Comparable { public let name: String public let commodities: [String] public let returns: Rates public static func < (lhs: AssetClass, rhs: AssetClass) -> Bool { lhs.name < rhs.name } public static func == (lhs: AssetClass, rhs: AssetClass) -> Bool { lhs.name == rhs.name } public func hash(into hasher: inout Hasher) { hasher.combine(name) } } It has a unique name, ...| Rob Napier
I’ve been thinking a lot about how to make PRs work better for teams, and a lot of my thinking has gone into how to show more compassion for the reviewer. Tell them your story. What was the problem? What did you do to improve it? How do you know it is a working solution (what testing did you do)? Why do you believe it is the right solution? Why this way rather than all the other ways it might be solved?| cocoaphony.micro.blog
This post is way off topic, and a bit in the weeds, and maybe even a bit silly, which is why I’m throwing it here rather than getting back to making my proper blog work. I really will do that, but… ok, not today. I’ve been trying to learn some abstract algebra. I never studied it in school, and sometimes I bump into people describing operations in “group-speak” (throwing around words like “abelian” and “symmetric group”), and I’d like to try to keep up with what they’re ...| cocoaphony.micro.blog
So you have a Swift Package Manager project, without an xcodeproj, and you launch Instruments, and try to profile something (maybe Allocations), and you receive the message “Required kernel recording resources are in use by another document.” But of course you don’t have any other documents open in Instruments and you’re at a loss, so you’ve come here. Welcome. (Everything here is from my own exploration and research over a few hours.| cocoaphony.micro.blog
So, all my tweets about C++ and Rust brings me to a minor announcement. After nearly 6 years with Jaybird, learning so much about Bluetooth on iPhones and custom firmware and audio, it’s time for something new. Luckily, Logitech is large enough that I can change jobs without changing my health insurance. In October I’m moving to the Logitech Software Engineering team. My exact projects are still up in the air, but I’ll likely work mostly on desktop products and interfacing with peripher...| cocoaphony.micro.blog
The NSRange for a full string is NSRange(location: 0, length: (text as NSString).length). You cannot use text.count for this. NSRanges on strings are based on UTF-16 code points, not Swift Characters. A character like 👩👩👧👧 has a .count of 1, but a .length of 11. ObjC-based NSRange APIs (even ones ported to Swift) need the latter. Swift interfaces (which use Range rather than NSRange) need the former. Whenever possible, avoid NSRange.| cocoaphony.micro.blog
We spend so much time drilling algorithmic complexity. Big-O and all that. But performance is so often about contention and memory, especially when working in parallel. I was just working on a program that does Monte Carlo simulation. That means running the same algorithm over the same data thousands of times, with some amount of injected randomness. My single-threaded approach was taking 40 seconds, and I wanted to make it faster.| cocoaphony.micro.blog