Honest question. Not trying to troll. One of the pitches in the earlier days was “C/Objective-C OK, but you can’t write safe/next level code with it—-Swift will close that gap.”
N years later, it doesn’t feel like there has been a step change in Apple software quality; if anything Apple software feels less solid, and looks cool “look what I did” extension points. I mean, some of the tings you could do with runtime categories, and runtime prototypes were really cool. Now when I work on my 2 apps that originally happily port to Swift/UIKit, I’m just left confused with how to make things work. I’m happy when it finally works, and don’t ever try to improve the thing, it’s too much work.
There’s lots of different variables at play here; I’m not trying to stretch inference too much. Heck, it could have been that with adding Swift to the mix, the forces that have contributed to reduced quality in Apples stuff would be even worse.
I’m just frustrated. When I work in Elixir, I’m like this is cool. When I work in Kotlin, I don’t feel like “Apples got a language like this too, but it’s got that extra special zing that used to make stuff Apple touched cool.”
I feel the same. Apple software quality certainly hasn’t increased. Years back I remember some apps crashing suddenly after updating MacOS. I checked the binary and saw they’d started adding Swift.
Half a decade later it seems like it should be better and Swift stuff should be stabilized. But nope, I’ve had more little glitches in both iOS and MacOS. It’s hard to say it’s due to Swift, and not management priorities. Still it feels partially related to Swift.
Swift’s goals are great, I like the syntax, but the language implementation seems to just special case everything rather than having coherent language design.
That and Swift de-emphasizes Obj-C message passing. I have a pet theory that message passing produces more robust GUI software that’s easier to adapt to complex needs.
It is not just the language but the frameworks. SwiftUI is a wreck, and still not mature even after 6-7+ years in 'production'. You still have to drop to UIKit to do advanced UI, and for what it is, SwiftUI is just not practical enough for cases that are not trivial.
The trouble is that all new kids/engineer are learning it first, which means software wont get better. Apple need to improve it first, and I don't see advanced folks ditching UIKit anytime soon for advanced UI.
I have a good bug right now. My wife bought a Macbook Air. I use High DPI and she does not. It is impossible to switch between users in this situation, one of the core functionalities of the computer is just broken. Makes me wonder if anyone at Apple uses these computers..
That doesn’t mean much. Swift is new. Usable Swift even more so. All of the apps Apple propose have legacy. New apps from now (e.g. Invites) will be much more interesting.
> Swift’s goals are great, I like the syntax, but the language implementation seems to just special case everything rather than having coherent language design.
This could not be furthest for the truth. The entire process of proposing a new language feature to getting it implemented and shipped is out in the open for everyone to participate/see.
Software written in a simpler language like Objective-C - verbose, fast to grok and fast to compile is actually more maintainable in the long run than a so-called "developer friendly", humongous, complex and slow-compilation language like Swift.
A lean language reduces the surface area for beautiful expressiveness by clever people - making sure the dumb/junior guy who is maintaining your project in the future can actually fully understand what is written. And it can build and run fast - so you can iterate and test out software behaviors fast.
No one in this world is immortal. If it takes too much time to grok code, write/compile/run tests - a developer will be disincentivized to do so, no matter how amazing the language features are.
My guess is that Swift has adversely affected Apple's overall software quality. As more software moved from Objective-C to Swift, quality has dropped precipitously.
It's easier to read and navigate a well-written Swift codebase than a well-written Objective-C codebase
Conversely, it's easier to debug an Objective-C app than a Swift app, simply because compiling and debugging is so much faster, and debugging so much more reliable
I don't know about a software quality drop being attributable to the migration to Swift. So many other things have also happened in that time — much more software that Apple produces is heavily reliant on network services, which they are not very good at. I find Apple's local-first software to be excellent (Final Cut Pro X, Logic, Keynote) and their network-first software is hit-or-miss
They have also saddled developers with a ton of APIs for working with their online services. Try to write correct and resilient application code that deals with files in iCloud? It's harder than it was to write an application that dealt with only local files a decade ago!
Swift is easy to blame, but I don't think it's responsible for poor software. Complexity is responsible for poor software, and we have so much more of that now days
There's a limit to how "lean" a safe, low-level language can be. Rust is leaner and simpler than Swift but not by much, and pretty much all of its outward features are "load bearing" to a far greater extent than Swift's.
(People have tried to come up with simpler languages that still preserve safety and low-level power, like Austral - but that simplicity comes at the cost of existing intuition for most devs.)
As someone frequently flipping between Swift and Kotlin, while I don’t necessarily feel like Swift is massively superior, I often find myself thinking “why is this so quirky and pedantic” when writing Kotlin.
For example, I really really wish Kotlin would adopt Swift style if let/guard let statements. Kotlin smart casting doesn’t work just often enough to not be able to consistently rely on it and the foo?.let { } syntax is ugly.
Combined with the JVM warts of gradle and jankiness of code stripping and obfuscation, generally speaking if I could opt to use Swift in place of Kotlin for Android dev I would do so in a heartbeat.
Ha, I switch between the two as well, but I feel the opposite. Kotlin is much more intuitive for me, and Swift is more clunky. I do miss guard lets in Kotlin, but that’s about it.
I have been skeptical of Swift ever since I heard the original goal was the one language to rule them all from Assembly to Javascript. When something is too good to be true it probably is. But I have also given Apple plenty of benefits of doubt.
It seems Swift 6.2 is still unfinished and is acting more like Java. Eternal evolution of language. While it is popular among tech and HN crowds to have new language and framework to play around and work. It brings particular little if not negative user experience in terms of final products. I often wonder if Apple could just have some light touches of improvement on Objective-C in the past 10 - 12 years and instead focuses on actual OS and Apps quality.
It is this lack of focus that has been with Apple since Steve Jobs left.
> It seems Swift 6.2 is still unfinished and is acting more like Java. Eternal evolution of language. While it is popular among tech and HN crowds to have new language and framework to play around and work
You can have both. Rust feels "mature" and "finished" if you stick to the stable featureset, but it's still bringing compelling new features over time in spite of that. But this can only be achieved by carefully managing complexity and not letting it get out-of-hand with lots of ad-hoc special cases and tweaks.
Umm...Java is extremely conservative in adding new features. Not really sure you can compare to Swift that throws 10x the features in with every major release.
It's second system syndrome combined with the fact that Objective C and the NeXT underpinnings were put together by a team of truly the greatest minds of a generation.
Swift was put together by some great minds, and some minds, Apple still attracts talent, but in far lower density. This isn't even a jab, just from the fact that they are far larger and the talent pool is smaller with far more competition.
What percentage of genius level developers want to work for a company where they can't talk about their work and generally get zero public credit?
Swift wasn't designed to solve any of the problems Apple engineers had writing customer-facing software. It was a shiny new language which could be marketed to third parties as something modern and familiar, unlike Objective-C with its odd mix of C and square brackets.
Surely developer productivity and maintainability have increased from the ObjC days, no? Swift criticisms aside, it certainly allows access to more ergonomic high-level coding patterns.
A big one that I feel is under appreciated is how Swift has rooted out nearly all passing around of untyped data, untyped dictionaries, casting without checking, etc in Apple platform projects.
I don’t mind Objective-C when I’m the one writing it and can ensure that the code is responsibly written, but it wasn’t unusual to have to work on existing Obj-C codebases littered with untyped data, casts, etc some amount of which was inevitably erroneous and only seemed to work correctly. Chasing down the origin points of data, fixing a laundry list of method selectors, and adding in checks always sucked with the compiler doing little to give you a hand. With Swift, even in codebases with poor hygiene fixing things is easier since the compiler will yell when something’s wrong.
The article doesn’t give enough attention to the glacial but steady changes in the ownership model that will have great benefit in avoiding copies in value types, Swift’s strength and Achilles heel.
I have to say Paul Hudson has almost single-handedly taken over communicating the essentials of Swift to the world; he’s fantastically reliable, brief but enthusiastic, guiding people around the many pitfalls.
Agree on Paul Hudson being great, but not so much on the guiding around the pitfalls. One big issue with the Swift community in general in my opinion is that a lot of the community content is incredibly shallow. Most of them are fine with "there's this feature and you can do X with it, cool right?" style-content, meaning very few people actually take the time to explain what the trade-offs are / performance considerations / how things work under the hood, and IMO this took a huge negative hit in the average skill level of Swift developers.
I think one of the problems is that the people who are actually using the language features generally don't have time to do it, Apple doesn't do it themselves, and Paul Hudson has 300 new features a year to view. Plus, iOS developers cargo cult harder than any other programming community I've come across, and this generally doesn't work really well if your explanation is difficult to quickly convey.
Agreed about Paul Hudson. He also just seems like a genuinely nice guy. I was kind of shocked to receive an email from him out of the blue last weekend (well, from GitHub, but with his name in the "From" field). Turns out it was about a PR [0] to one of my packages where he fixed typos in the README.
Free-form identifiers are neat for test-case naming, but not for `HTTPStatus.`404``. I think having `HTTPStatus.Error404` was a bad idea to begin with. Just use semantic names like `HTTPStatus.NotFound` and you wouldn't have a problem in the first place. Now, a single character typo can easily make a 404, 403 and create a bug. It's less of a problem with semantic names.
If you want constrained numeric types in Swift, that's another problem to tackle. But `HTTPStatus.`404`` seems to be the least ideal way to go about it. It lets you do stuff like to declare `HttpStatus.`404`` with a value of 403 too.
Messing up Unauthorized vs Forbidden is a semantic problem, but 403 vs 401 can be either semantic or syntactical. It’s not like you’d mispress a key and get Forbidden instead of Unauthorized.
> Just use semantic names like `HTTPStatus.NotFound` and you wouldn't have a problem in the first place.
Have to disagree there: when I tried re-implementing a basic websocket server in multiple languages (https://news.ycombinator.com/item?id=43800784), I found it so frustrating when they'd insist on hiding the raw close-codes behind pretty names, because it meant having to stop what I was doing to jump into the documentation to figure out what pretty name they gave a particular close code.
If you don’t want to deal with that, you can just use the number. Some APIs have integer overloads for that purpose, but you can also typecast. I don’t find HTTPStatus.`1003` more helpful than 1003.
Yeah, the feature is mostly about test cases and macro generated code. The numeric property names are far less useful, as the good syntax requires tick marks: .`404`
As he mentioned in a forum post some years ago, Chris wanted the language to be more modular, but Apple's drive for adding features to it sets very different priorities.
To be fair, every new language version usually includes things that eliminate those special cases making writing the code more straightforward. Like the described support of functions in key paths, or the ability to set default global actor isolation.
Lot of nice improvements here. I'm actually quite liking the async API after using it in a couple small apps and learning the fundamentals.
I really wish the entire Swift team would spend a quarter fixing bugs and improving the compiler speed, though. So many trivial SwiftUI cases trigger the "this is too complex for the compiler" errors which are so frustrating to fix.
I've been starting to use Swift again lately after like four years, and while the language is beautiful & the package management story is now a LOT better with SwiftPM, I found that none of it plays nicely with XCode, Simulator, or anything to do with iOS/macOS development -- its primary use-case!
I found myself awestruck that I *HAD* to use XCode or xcodebuild, and could not just run `swift build` and generate an iOS app.
In the end, I had to:
- compile the .app structure myself
- run codesign manually
- manage the simulator manually
- bundle xcAssets manually
- provide swift linker flags manually targeting the toolchain/sdk I needed
- manually copy an embedded.mobileprovision
It was a good learning experience, but what's the story here? Did Apple just give away Swift to the OSS community and then make no ongoing effort to integrate their platforms nicely into the non-xcode build tooling? Looking into https://github.com/stackotter/swift-bundler
The Swift language team has recently open sourced swift-build, and the community's assumption is that it was done in order to eventually move everything away from xcodebuild to swift-build, which would let you build an app from swift packages and fully break from Xcode: https://github.com/swiftlang/swift-build
You are talking about the language but bringing up an example of creating an app for an Apple platform. Regardless of the language you will have to create app bundle structure, copy assets inside, add mobile provision and sign it.
If you ask me, those platform specific things should never be integrated part of the language.
Sure, but developing for Apple's platforms is Swift's primary use. I'd say Dart & Flutter is a fair comparison:
As flawed as they are in my eyes, its dev tooling quality is something I appreciate and wish I saw here. There are two CLIs, one for the language (Dart) and one for the framework (Flutter). Some would say that the CLI equivalent would be xcodebuild, but that depends on the complex .xcodeproj/.xcworkspace structure and still requires XCode to be installed.
As far as I could tell, if you create a Main.swift file, you can't just open that in XCode and start running it as an iOS/macOS application, and instead have to create a .xcodeproj/.xcworkspace through XCode, and add your Swift to the scaffolded project - this seems backwards to me.
(I then separately complained at all the steps it took to get it running without XCode, as I didn't want to be locked into using it)
Not op, but I think "doesn't play nicely" means does not work so you have to do it in other ways. This has been my experience as well, albeit it was couple of years ago.
> None of the decision-makers seem to have the sense or incentive to say "no" to anything.
How could you know that? Not all the 'no's show up as a proposal. The proposal template also has an "Impact on ABI" section which you can use to guide your "can I ignore it"-sense.
> It sure feels like Swift governance is broken.
What is the actual problem though? Not enough features that you would use? But I don't see how this is a governance problem
Java governance: slow at times but mostly sane.
C++ governance: I won't even open this can of worms.
Swift governance according to you: too many features I will ignore.
I enjoy "bloated" languages. Many languages are bloated nowadays, but the community agrees what set of features to use, what to avoid. Still, those rare features can be useful for stuff like making DSLs through clever use of the language.
It's much worse to have a minimal language that takes years to add new features, like how Go took over a decade to add generics.
> InlineArray does not conform to either Sequence or Collection
Why not? Does this mean I need to make a struct which wraps InlineArray and implements Collection? Why didn't they do that?
EDIT: found the answer (I still have concerns):
> While we could conform to these protocols when the element is copyable, InlineArray is unlike Array in that there are no copy-on-write semantics; it is eagerly copied. Conforming to these protocols would potentially open doors to lots of implicit copies of the underlying InlineArray instance which could be problematic given the prevalence of generic collection algorithms and slicing behavior. To avoid this potential performance pitfall, we're explicitly not opting into conforming this type to Sequence or Collection.
Tl;dr: Sequence and Collection are incompatible with noncopyable types and conditionally conforming when elements are copyable would result in too many implicit copies. They’re working on protocols to cover noncopyable collections such as this, which will probably have a similar API shape.
Interesting; if I'm understanding correctly, it sounds like Swift doesn't have a standard lazy iteration API yet? I would have guessed that it did if asked before reading this, but it's good to hear that they're already working on it. Since I feel super spoiled by lazy iterators in Rust, I'm super curious if anyone has more Swift experience and could chime in on if there are other language features or APIs that might illuminate why there wasn't as much of a need for this earlier; my general perception of Swift as an outsider is that it tends to have pretty well-thought out decisions based on factors that I just happen not to know about personally (e.g. compatibility with other parts of the Apple software ecosystem or different priorities due to the domains Swift is often used in compared to the type of stuff I work on personally).
N years later, it doesn’t feel like there has been a step change in Apple software quality; if anything Apple software feels less solid, and looks cool “look what I did” extension points. I mean, some of the tings you could do with runtime categories, and runtime prototypes were really cool. Now when I work on my 2 apps that originally happily port to Swift/UIKit, I’m just left confused with how to make things work. I’m happy when it finally works, and don’t ever try to improve the thing, it’s too much work.
There’s lots of different variables at play here; I’m not trying to stretch inference too much. Heck, it could have been that with adding Swift to the mix, the forces that have contributed to reduced quality in Apples stuff would be even worse.
I’m just frustrated. When I work in Elixir, I’m like this is cool. When I work in Kotlin, I don’t feel like “Apples got a language like this too, but it’s got that extra special zing that used to make stuff Apple touched cool.”
Half a decade later it seems like it should be better and Swift stuff should be stabilized. But nope, I’ve had more little glitches in both iOS and MacOS. It’s hard to say it’s due to Swift, and not management priorities. Still it feels partially related to Swift.
Swift’s goals are great, I like the syntax, but the language implementation seems to just special case everything rather than having coherent language design.
That and Swift de-emphasizes Obj-C message passing. I have a pet theory that message passing produces more robust GUI software that’s easier to adapt to complex needs.
This could not be furthest for the truth. The entire process of proposing a new language feature to getting it implemented and shipped is out in the open for everyone to participate/see.
https://github.com/swiftlang/swift-evolution
A lean language reduces the surface area for beautiful expressiveness by clever people - making sure the dumb/junior guy who is maintaining your project in the future can actually fully understand what is written. And it can build and run fast - so you can iterate and test out software behaviors fast.
No one in this world is immortal. If it takes too much time to grok code, write/compile/run tests - a developer will be disincentivized to do so, no matter how amazing the language features are.
My guess is that Swift has adversely affected Apple's overall software quality. As more software moved from Objective-C to Swift, quality has dropped precipitously.
Conversely, it's easier to debug an Objective-C app than a Swift app, simply because compiling and debugging is so much faster, and debugging so much more reliable
I don't know about a software quality drop being attributable to the migration to Swift. So many other things have also happened in that time — much more software that Apple produces is heavily reliant on network services, which they are not very good at. I find Apple's local-first software to be excellent (Final Cut Pro X, Logic, Keynote) and their network-first software is hit-or-miss
They have also saddled developers with a ton of APIs for working with their online services. Try to write correct and resilient application code that deals with files in iCloud? It's harder than it was to write an application that dealt with only local files a decade ago!
Swift is easy to blame, but I don't think it's responsible for poor software. Complexity is responsible for poor software, and we have so much more of that now days
(People have tried to come up with simpler languages that still preserve safety and low-level power, like Austral - but that simplicity comes at the cost of existing intuition for most devs.)
For example, I really really wish Kotlin would adopt Swift style if let/guard let statements. Kotlin smart casting doesn’t work just often enough to not be able to consistently rely on it and the foo?.let { } syntax is ugly.
Combined with the JVM warts of gradle and jankiness of code stripping and obfuscation, generally speaking if I could opt to use Swift in place of Kotlin for Android dev I would do so in a heartbeat.
It’s a set of tools intended to do just that.
https://skip.tools/
It seems Swift 6.2 is still unfinished and is acting more like Java. Eternal evolution of language. While it is popular among tech and HN crowds to have new language and framework to play around and work. It brings particular little if not negative user experience in terms of final products. I often wonder if Apple could just have some light touches of improvement on Objective-C in the past 10 - 12 years and instead focuses on actual OS and Apps quality.
It is this lack of focus that has been with Apple since Steve Jobs left.
You can have both. Rust feels "mature" and "finished" if you stick to the stable featureset, but it's still bringing compelling new features over time in spite of that. But this can only be achieved by carefully managing complexity and not letting it get out-of-hand with lots of ad-hoc special cases and tweaks.
Swift was put together by some great minds, and some minds, Apple still attracts talent, but in far lower density. This isn't even a jab, just from the fact that they are far larger and the talent pool is smaller with far more competition.
What percentage of genius level developers want to work for a company where they can't talk about their work and generally get zero public credit?
Swift was never going to make Apple software great (nor Go or Rust or anything else for anyone else).
Though, honestly, if you're thinking about computer languages in terms of cool, you're going in the wrong direction.
Deleted Comment
I don’t mind Objective-C when I’m the one writing it and can ensure that the code is responsibly written, but it wasn’t unusual to have to work on existing Obj-C codebases littered with untyped data, casts, etc some amount of which was inevitably erroneous and only seemed to work correctly. Chasing down the origin points of data, fixing a laundry list of method selectors, and adding in checks always sucked with the compiler doing little to give you a hand. With Swift, even in codebases with poor hygiene fixing things is easier since the compiler will yell when something’s wrong.
I have to say Paul Hudson has almost single-handedly taken over communicating the essentials of Swift to the world; he’s fantastically reliable, brief but enthusiastic, guiding people around the many pitfalls.
[0] https://github.com/visfitness/reorderable/pull/2
Dead Comment
If you want constrained numeric types in Swift, that's another problem to tackle. But `HTTPStatus.`404`` seems to be the least ideal way to go about it. It lets you do stuff like to declare `HttpStatus.`404`` with a value of 403 too.
It's like when you see a poisonous snake and can't remember if "red touches yellow" is paired with "deadly fellow" or "friendly fellow".
I'm not seeing why it's worth a whole language feature to avoid prefixing strange identifiers.
Not a fan personally, but Swift is littered with little "niceties" (complexities) like this.
Have to disagree there: when I tried re-implementing a basic websocket server in multiple languages (https://news.ycombinator.com/item?id=43800784), I found it so frustrating when they'd insist on hiding the raw close-codes behind pretty names, because it meant having to stop what I was doing to jump into the documentation to figure out what pretty name they gave a particular close code.
All I wanted was to return 1003 (https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1) if the websocket sent a string message, but:
- Dart calls this "unsupportedData" (https://api.dart.dev/stable/latest/dart-io/WebSocketStatus/u...)
- Java-Websocket calls this "REFUSE" (https://javadoc.io/doc/org.java-websocket/Java-WebSocket/lat...)
- Ktor calls this "CANNOT_ACCEPT" (https://api.ktor.io/ktor-shared/ktor-websockets/io.ktor.webs...)
And some others:
- .NET calls this "InvalidMessageType" (https://learn.microsoft.com/en-us/dotnet/api/system.net.webs...)
- libwebsockets calls this "LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE" (https://libwebsockets.org/lws-api-doc-main/html/group__wsclo...)
Just... why? Just call the thing 1003 and link to the spec.
If you can't figure out what stripHTMLTagsFromString() does, you have way bigger problems than a lack of spaces.
— Chris Lattner, 2024
https://blog.jacobstechtavern.com/p/apple-is-killing-swift
To be fair, every new language version usually includes things that eliminate those special cases making writing the code more straightforward. Like the described support of functions in key paths, or the ability to set default global actor isolation.
I really wish the entire Swift team would spend a quarter fixing bugs and improving the compiler speed, though. So many trivial SwiftUI cases trigger the "this is too complex for the compiler" errors which are so frustrating to fix.
I found myself awestruck that I *HAD* to use XCode or xcodebuild, and could not just run `swift build` and generate an iOS app.
In the end, I had to:
- compile the .app structure myself
- run codesign manually
- manage the simulator manually
- bundle xcAssets manually
- provide swift linker flags manually targeting the toolchain/sdk I needed
- manually copy an embedded.mobileprovision
It was a good learning experience, but what's the story here? Did Apple just give away Swift to the OSS community and then make no ongoing effort to integrate their platforms nicely into the non-xcode build tooling? Looking into https://github.com/stackotter/swift-bundler
If you ask me, those platform specific things should never be integrated part of the language.
As flawed as they are in my eyes, its dev tooling quality is something I appreciate and wish I saw here. There are two CLIs, one for the language (Dart) and one for the framework (Flutter). Some would say that the CLI equivalent would be xcodebuild, but that depends on the complex .xcodeproj/.xcworkspace structure and still requires XCode to be installed.
(I then separately complained at all the steps it took to get it running without XCode, as I didn't want to be locked into using it)
They're just shoveling stuff in to the language.
Individually, most items aren't so bad, but collectively they've got a mess and it's getting bigger fast.
None of the decision-makers seem to have the sense or incentive to say "no" to anything.
It's sad, because the language had such promise and there are some really nice things in there.
Well, at least it's relatively easy to avoid or ignore.
How could you know that? Not all the 'no's show up as a proposal. The proposal template also has an "Impact on ABI" section which you can use to guide your "can I ignore it"-sense.
> It sure feels like Swift governance is broken.
What is the actual problem though? Not enough features that you would use? But I don't see how this is a governance problem
Java governance: slow at times but mostly sane. C++ governance: I won't even open this can of worms. Swift governance according to you: too many features I will ignore.
I enjoy "bloated" languages. Many languages are bloated nowadays, but the community agrees what set of features to use, what to avoid. Still, those rare features can be useful for stuff like making DSLs through clever use of the language.
It's much worse to have a minimal language that takes years to add new features, like how Go took over a decade to add generics.
Why not? Does this mean I need to make a struct which wraps InlineArray and implements Collection? Why didn't they do that?
EDIT: found the answer (I still have concerns):
> While we could conform to these protocols when the element is copyable, InlineArray is unlike Array in that there are no copy-on-write semantics; it is eagerly copied. Conforming to these protocols would potentially open doors to lots of implicit copies of the underlying InlineArray instance which could be problematic given the prevalence of generic collection algorithms and slicing behavior. To avoid this potential performance pitfall, we're explicitly not opting into conforming this type to Sequence or Collection.
Tl;dr: Sequence and Collection are incompatible with noncopyable types and conditionally conforming when elements are copyable would result in too many implicit copies. They’re working on protocols to cover noncopyable collections such as this, which will probably have a similar API shape.