Hi HN! We're back with another post describing more detail about how we built Bitrig's interpreter for Swift in Swift, this time going into how we're converting the code into bytecode.
Yeah there was definitely some back and forth about it before we were eventually approved.
In a sense, this isn't very different from what React Native does (run interpreted code that calls out into native code), just with Swift instead of JavaScript. There used to be JavaScript-specific requirements in the guidelines, but that has been loosened since Swift Playgrounds was released. Now there are Python IDEs, Jupyter Notebooks, and other apps running arbitrary code in the App Store.
The root of these restrictions is to try and prevent people from using dynamic code to bypass App Store reviews. If you're planning to change the functionality of your app then you must submit it for review.
There's definitely a cost: everything is type-erased and there's a lot more indirection than there would be if the code was compiled. But you usually don't hit performance issues because most app code (especially in the UI) is just a thin layer calling into the OS frameworks. The framework code does the heavy lifting and is all compiled.
The places you can hit performance issues are things like when the app itself has a tight loop that's doing a lot of work.
I refer to Swift as a "compiled language" because no officially provided interpreter exists for it.
Bitrig runs Swift apps which are dynamically generated by an LLM on the iPhone, despite the iPhone strict security provisions (e.g. inability to write executable pages of memory). The way we do this is by parsing the generated Swift code and mapping that to the compiled calls to the libraries that come in the OS. It's pretty weird, but we think it's worth it to get the ability to immediately render the generated code on the phone.
I think that's a more accessible explanation. Consider folding that into the article's introduction.
Is the idea that your interpreter is signed, and then you translate the user's arbitrary unsigned Swift code into calls to other already-signed code that ships with iOS?
That's not really been something we'd been considering, but yeah I think we probably could. We're primarily using the interpreter to render SwiftUI views, but it supports running arbitrary Swift expressions or statements.
Yeah you could! The only caveat is that either the whole app, or at least the part of the app showing the view you want to replace, would have to be running via the interpreter.
We're very interested in using the interpreter to improve the Swift developer experience in more ways like that.
I bet you could make a ton of money just selling a better dev experience as an xcode add-on to Swift devs without even having the AI component. (But making an app on my phone with AI is unbelievably neat!).