This was an awesome talk. I really wish he went more into their plans to put Swift in the kernel and the bullet point of expecting the language to "scale down to a minimal runtime" (~7:41).
Interoperability is about practicality and performance cost. I think Swift is quite practical and efficient in this regard - from day 1 it has near-zero C-lang integration costs, and now it has C++ support.
Also, https://github.com/swiftwasm shows how the modularity pays off. Comparing it to the other languages that got stuck with incompatible frame conversion (Golang) or JIT memory management problems (JVM) it's not bad at all.
I'm quite bullish on this method of cross-platform i.e. a common shared core leveraging native UI toolkits. Every incarnation of cross-platform on the market today sits somewhere between mediocre and bad in terms of the resulting UX. This approach strikes a good balance between sharing code and being platform native I think. Swift is a good contender for doing this and so is, I think, Rust.
I feel like the problem with Swift in this context is its relationship with Foundation, its standard library. There are at least three versions of it now. The internal version that ships with Apple OSes, then are the forks swift-corelibs-foundation and swift-foundation, these are, as far as I know, incomplete or behave slightly differently on Linux.
swift-foundation is the newest and most likely the future. However, it's unclear when or if it will ever be production ready. Apple doesn't appear to be dedicating that much engineering effort towards it right now.
Eh, I wouldn’t call Foundation its standard library - it sits somewhere in between your traditional stdlib (including things like Date/Time models) and third-party dependencies (things like networking requests). There’s no functionality in Foundation that is absolutely core to the language and that you can’t avoid.
I agree with you the various forks are confusing, but disagree that Apple isn’t putting effort towards the new one - it was only announced earlier this year, and is looking like it will be ready for WWDC is 2024. Which, given the sheer scope of the project (completely rewriting everything from the ground up in Swift), would be quite a fast turnaround time.
>Eh, I wouldn’t call Foundation its standard library...
You're absolutely right, because the Swift Standard Library is a separate thing. It contains only the absolute essentials such as Int, String or Array:
> There’s no functionality in Foundation that is absolutely core to the language and that you can’t avoid.
Is that why they're splitting the newer one into further SPM modules? There seems to be "FoundationEssentials" listed in that package.
> but disagree that Apple isn’t putting effort towards the new one - it was only announced earlier this year, and is looking like it will be ready for WWDC is 2024
Oh, interesting, where did you find this information? I follow the project on Github and got the impression it had slowed down since its announcement.
Kotlin is a much more likely candidate. Excellent IDE support, deep integration with Java, already the go-to language for Android, many years of production and less "different" than Rust.
Kotlin running on the JVM is a disadvantage outside of Android though in a lot of spaces. Rust/Swift/Go will use a fraction of the ram to run a server application than Kotlin will.
One big potential pitfall people seldom discuss is that Java is moving in a different direction and taking JVM along with it. This will cause problems in the future for Kotlin in areas such as reification and nullability.
Kotlin compiles to the native architecture on non-JVM targets. It works just as well as using Swift on non-Apple targets, that is to say it's a bit of a pain development-wise but runs fine once you have your tool chain and interop code setup. Honestly versus either, I'd recommend dart/flutter. Insanely productive, native compiled code, performant UIs that reasonably emulate native (although I'd recommend avoiding that and going stylized - users are more willing to accept something different than something close but not quite right). And interop with C++ is pretty easy.
Flutter is trash (slow and ugly) built on a dead end language (dart).
Any company building their business on flutter is setting themselves up for disaster and an expensive double-rewrite to native, while having a useless engineering team because they skilled up previously mentioned dead-end.
the article displays a couple of screenshots on why it's a poor experience, bottom navigation is to small and the back button is behind the camera, it's very unlikely to be fixed at the component level so devs end fixing these issues themselves by creating a new component that may not behave entirely as the system one, using the device's safe area
I don’t see the same issues you mentioned when checking the screenshots on their App Store / Play Store pages. But that was a good catch of yours.
I’m relatively confident that they used a device frame around their actual screenshots, which leads back to those issues you mentioned. You can tell that they’ve used different device frames in their current store listings compared to the realistic looking ones on the aforementioned Flutter showcase page.
This whole process can even be automated. I’m talking about a CI/CD workflow that takes screenshots of specific pages, and adding device frames around them etc. See this tool for example: https://docs.fastlane.tools/actions/frameit/
So if Kotlin targets two completely seperate platforms (JVM and native) does that mean any C++ interop would have to be written seperately and differently for each of those platforms?
This is correct but not because of Java. The android SDK is terrible because of many reasons.
Which is also the reason why kotlin is so popular there. Using extensions function and concise syntax you can build clutches around this terrible abomination of an SDK.
Exactly right. It seems difficult for so many folks to understand Kotlin is not some independent language from scratch but another JVM language trying to avoid Java's supposedly shortcomings. And Kotlin/Native/Web doesn't matter because core language design is simply informed by Java and other JVM ecosystem languages' features and limitations.
I think Kotlin is newer/better horse cart to Java's old cart rather than automobile.
Further as others have mentioned Java's 6 month release cycle and ton of changes at language/VM/library layers will make it difficult for Kotlin to choose between complying to latest JVM or chart an independent path.
I agree, a huge driver for me leaving the Java ecosystem for Go was the JVM. Maybe Kotlin native can address that, but despite what people in the Java world seem to believe, the JVM is a big disadvantage.
The JVM may be full of technology that’s indistinguishable from magic, but deployment is a pain in the ass.
Maybe things have changed in the last few years but - having to ship a huge file tree alongside the actual binary (or binaries because JARs are also a nightmare), and the slow startup time due to the need to interpret/compile bytecode instead of just running machine code, make Java really unpleasant to use in many common use cases.
Well I shipped fat jars using capsule more than 15 years ago without any issues. Nobody ships file-trees.
Also the Startup depends on how much memory you allocate, but much of it is due to verifying class security, a feature that other runtimes don't even have. Or badly used reflection, another feature others don't have.
In any case I really never found it an issue if a server takes 3 seconds to start and I never understood why people complained about Java startup. My guess is they complain about clunky desktop application with a million classes written in it.
Regarding the bytecode: the interpretation and just in time recompilation gives Java sometimes better than native performance.
It also allows you to hook into the code on the fly and transform it with agents. Can native do that?
The file tree I was referring to is the JRE, not the code.
In any case, if Java works for you then that’s great. I’m just relating my own experience, where I found that the need for a JVM was less of a blessing than a curse.
As a former C developer who has been using Java for 20+ years, moving to Go was like lifting a weight off my shoulders. (I suspect I’d have felt the same with Rust, Swift or any other modern AOT language). It’s so refreshing to just have a binary, and be able to execute it, and not worry about a pile of irrelevant external factors.
The JVM uses as much RAM as you allocate in your program. If you get along with 4 megabytes then you can set the maximum memory of the JVM to 4 megabytes and it will never use more than that.
Based on the title I really thought this would about the SWIFT (messaging system) and interoperability (Interledger protocol). I really need to stop reading crypto articles. Its taking over my tech side.
SWIFT as in the Fintech/banking thing? It's amazing how fast my memory of things goes after I switch jobs, I had to ask ChatGPT to refresh my memory.
"""
SWIFT stands for the Society for Worldwide Interbank Financial Telecommunication. It is a global messaging network used by banks and financial institutions to securely and efficiently exchange information, particularly for international money transfers and transactions. SWIFT codes are used to identify banks and facilitate the transfer of funds between them. It plays a crucial role in international banking and financial communication.
"""
I didn't know SWIFT was involved at all in crypto stuff, at least not directly. I guess finance is the world's most interconnected network, however, so I shouldn't be too surprised.
Many people outside of the finance industry first learned about SWIFT when it was in the news that Russian banks had been excluded from the network as a consequence of their country’s violations of international law and attempt to conquer Ukraine.
SWIFT’s relevance to cryptocurrency is most likely the cryptocurrency community’s aspirations of creating an alternate method for transferring wealth that is not limited by international borders or implicitly required to respect international sanctions. Legally, citizens in countries respecting the international law can still be liable for violating sanctions regardless of the method they use to transfer assets, so I don’t completely understand the how cryptocurrency is a superior way to launder money when the transactions occur on a public block chain.
I would like to see a comparison of how this compares to Rust. In terms of interoperability it has Cxx (https://cxx.rs) to offer safe bindings to C++ but also has great support for Android, Linux and many other systems. You don't even need to hack together Windows bindings (as explained in the blog post) because Microsoft offers official bindings (https://crates.io/crates/windows). I'm not sure if I'd call it a superpower if any potential interoperability has to be written to be used (compared to it already being available). Or rather, in comparison to what is interoperability a Swift superpower? Certainly not C++ or C which can be used in a far wider set of targets.
Swift simply has good interop with shared objects written in Swift. You're not forced to go through a raw C ABI for everything, whereas you have to do that in Rust (unless your shared objects are part of the same build). There are crates to make interop a bit easier, but they're not standard in any real sense.
The flip side though is that once you have to build a raw C API/ABI for your shared object written in Rust, it becomes usable with any other language that has good FFI with C, which is most of them.
I've worked both with the Swift C++-Interop project and I've also spoken to the author of cxx.rs a little bit. The two approach the problem differently.
Swift's approach is that you only need to provide a header (which you likely already have), and the compiler does all the rest to handle the bridging for you. cxx.rs' approach is that you use this crate to write a bridging file and so long as you follow the type set that cxx.rs understands you have a bridge (int, char, std::string, std::unique_ptr etc).
They're both good approaches but the Swift approach is definitely much more ambitious and more user-friendly to the programmer.
I don't know, I left Swift (although I like the language) because it is not interoperable whatsoever, in the sense that you can use it on whatever platform you like. I switched to TypeScript.
I happily made the switch from Obj-C to Swift when it was announced, partly because Apple said they wanted to make it a true cross platform language.
So far that doesn't seem to have really happened and in the meantime I've switched to Typescript and more recently Dart (for Flutter), which currently both have much better cross platform stories.
Yes, exactly. Interoperable doesn't mean much if it is not properly cross platform. I've tried Dart for a project, and it worked OK, but in my opinion TypeScript is clearly the way to go in the foreseeable future.
Typescript is limited by V8 capabilities, and the constraints of a dynamic language JIT. To achieve best perfomance one needs to write C++ code as native modules.
Interoperable means a lot even inside Apple ecosystem, bringing all those C, Objective-C and now C++ code with ease into Swift projects.
Using Metal from Swift, althought implemented in Objective-C and C++, is already a productivity boost compared to anything that Microsoft has ever produced for .NET in regards to DirectX, not even XNA.
I'd note that I've seen cases where the V8 JIT was sufficiently good that thunking to C++ and back meant that the performance difference was minimal.
But that was for 'js library backed by C++' shaped cases whereas for performance critical app-specific code you probably want 'C++ library that presents a JS interface at the top level.'
If you are on the Apple platform only, Swift is great, and I enjoyed using Metal myself. But eventually I accepted how much it limited what I can do as a developer. So, I prefer TypeScript now. I am not touching C++ or stuff like that, if I need performance, I compile to web assembly, hopefully soon from my own language :-)
WebGPU + WebAssembly + TypeScript is going to be a pretty potent combo.
I doubt Swift + Metal is more performant. Actually, when I translated some Swift code to JavaScript, it ran faster.
I'd say there are plenty of use cases where access to 2015 hardware capabilities is more than enough, given that you will profit from any automatic speed improvements beyond 2015 hardware as well. Which features beyond 2015 are you referring to?
The code I ported wasn't Swift+Metal, it was just Swift. It certainly wasn't optimized in any way, but the Javascript one wasn't either. Javascript data structures are just faster, because they are fully imperative, the Swift ones are more expensive, despite some copy-on-write tricks. And remember, carefully written Javascript is just as fast as C.
Yes, if you need these things, you will have to go native (although you will probably automatically benefit from unified memory).
For many many things, you won't, and then the ability to target Apple/Windows/Linux with exactly the same code, pain-free GPU access etc, that's just great. The other day I checked if I can access from the browser the 3D coordinates of my space mouse, and it just works, based on a standard Web API (GamePad API). While from Swift, it would be a hassle to setup and maintain.
"if" exactly, Google has a tendency to drop projects out of nowhere, or to suddenly change course on it.
Another big "no" factor with Flutter for me is that it's its own ecosystem and language; React Native ties in with the greater React ecosystem and the even greater Node ecosystem, which gives you a lot of libraries, code examples, maintenance and improvements. Second, hiring is a major factor. You can assign most current-day web developers onto a RN project with little problems, whereas Flutter is a new language and skill set.
Sure it’s a valid concern. I’m building my own app so hiring isn’t a concern for me. So far I’ve found the Flutter library ecosystem to be more than adequate for my needs and I’m finding it a far more pleasant and productive platform than React Native to work in.
I always found RN very easy to get started with but over time as features get added and dependencies evolve RN apps become increasingly difficult to update and maintain.
Also React is one of those easy to learn but difficult to master technologies. I’ve interviewed a lot of people claiming to know React that I wouldn’t trust to build anything complex. There are just so many footguns.
Hmm...Swift never struck me as a particularly interoperable design. Really rather the opposite. It has weird and super-specific calling conventions, requires mangled identifiers, is uber-static, uses Swift syntax for its "module" files etc.
And it turns out...
"Instead, Swift embeds a copy of clang, the C and C++ compiler,"
...well gosh, you can brute force "interoperability" by simply creating the union of all the languages you "interoperate" with.
Don’t forget that this interoperability was put in place to support a specific engineering goal: to make it possible to slowly (over decades, probably) transition from 4 different languages (C, ObjC, C++, ObjC++) at every level of Apple’s stack towards a single memory-safe successor language.
Would you recommend they wait for some weird Java-esque 100% Pure implementation within the compiler itself before they can begin that work?
The ideal you’re suggesting is actually made more reachable by this work. One can imagine a Swift LLVM/Clang now.
Wow, I'm only three minutes in, but it's a good talk. Among other parts of Apple's ecosystem (especially Webkit would make sense to move to Swift for memory safety), imagine if they start incrementally moving llvm/Clang over to Swift using this, that would be very interesting.
> “Instead, Swift embeds a copy of clang, the C and C++ compiler,"
...well gosh, you can brute force "interoperability" by simply creating the union of all the languages you "interoperate" with.
That’s not what they do. To efficiently use C and C++ structs and classes from another language you have to know their layout and calling conventions.
With C and C++, you have to run the preprocessor and (e.g. for C++ templates) large parts of the compiler to reliably do that. How else are you going to figure out what foo_t and bar_t in header files mean?
If you need to run a compiler, using an existing compiler is the wise thing to do.
If you want to interoperate with C and C++ and could either make people specify low-level details of the interface themselves or process C and C++ header files to do it automatically. Obviously the latter is a much better interoperability solution.
Processing C and C++ header files means using a C/C++ compiler. It would hardly make sense to write a new one if there was a good one already available.
Sounds like the precursor to what Lattner is trying to do with Mojo: embed everything into a Frankenstein of a compiler and runtime. Time will tell if such a thing is maintainable.
My understanding is that they're talking about the Swift compiler having an embedded Clang, not embedding Clang into all binaries. So no, not much that can go wrong, the Swift and Clang compilers are both part of the same wider LLVM ecosystem so marry together neatly to be able to provide this interoperability.
"Introducing a Memory-Safe Successor Language in Large C++ Code Bases"
https://www.youtube.com/watch?v=lgivCGdmFrw