9 ms·
Interoperability Between Swift and C++
- flohofwoe 6y agoAll this effort for a highly specialized solution that only fixes one combination in a huge M:N matrix. Wouldn't it be better to start working on an "LLVM for language interoperability"? That way every language only needs to provide a connection to an intermediate specification, and it can connect to any language supporting that same specification. Currently this is done through C APIs (and it works well enough TBH), but plain C APIs lack annotations for higher-level concepts (like lifetime, bounds checking, etc). Why not work on a modern language interoperability standard instead? Being able to mix many different smaller and specialized languages in a single project instead of trying to create the "one universal language to rule them all" also would speed up language evolution, because less effort is wasted copying features from one "universal language" into other "universal languages", and as a bonus, operating system APIs following that standard would become language-agnostic.
- wffurr 6y agoThat's a grand idea, but there's good reasons to go to this effort for just C and C++. There's a whole lot of code written in both; their toolchains are highly portable; for a long time they were seen as the only languages that gave programmers the ability to write high-performing code; and they are both unsafe by default. Providing seamless bindings with a safe-by-default language like Swift is a way to move the whole systems programming field forward to a safe language, while maintaining compatibility with the enormous existing code base in the world.
- flohofwoe 6y agoSure, but Swift is just one of many modern and (less modern) high-level languages, it's not just about connecting Swift to other languages than C or C++. There's also D, Rust, Nim, Zig, Python, Java, C#, even Javascript (when calling WASM modules), etc... those would all benefit from a more modern (and standardized!) approach to language bindings (even if the target languages would only be C or C++, but why stop there). Apart from that "grand idea" I think a more realistic real-world solution for the C++ => Swift situation is to simply wrap the C++ API into a C API first, and then create a Swift API on top of the C API, instead of trying to somehow translate the C++ API directly to Swift. E.g. every C++ library should come with an optional C-API to simplify language bindings, or even just compiling that library into a DLL.
- wffurr 6y agoIf we focus just on the programming cases where C++ has been heavily used, you can narrow that list down to D, Rust, Nim, and Zig. Dynamic languages or those with a heavy runtime like Python, Java, C#, and JavaScript are substantially different use cases. Among those remaining, Swift has substantially more corporate backing, what with Apple relying on it for their massively successful iOS platform and Google trying to use it for TensorFlow. C wrapper for C++ APIs has long been standard practice, but adds a substantial maintenance burden to C++ library authors and does not address semantics in the host language, which is a major part of this proposal. The whole proposal is based around the idea of seamless Swift to C++ interoperability. C++ has a lot of higher-level concepts that potentially can translate to similar higher-level concepts in other languages; round-tripping through a C API loses all of that. To be clear, I like your idea - it's a grand one, and potentially solves the N+M problem once and for all. The real stumbling block for it is the C++ ABI and sheer mass of existing C++ code.
- jcelerier 6y ago> E.g. every C++ library should come with an optional C-API to simplify language bindings, or even just compiling that library into a DLL. hard to do without incurring additional dynamic allocations though. e.g. how would you make, say, an API that wraps construction / doing stuff / destruction of something that'd look like this : namespace mylib { struct node { std::vector<node> children; std::optional<float> value; }; } in C you'd likely have to have something that looks like mylib_node* mylib_node_alloc(void); void mylib_node_free(mylib_node*); // and then... float* mylib_node_value(mylib_node*); // this ? float mylib_node_value(mylib_node*, int* ok); // or this ? void mylib_node_set_value(mylib_node*, float value, int set); // then there's this ? void mylib_node_set_value(mylib_node*, float* value); // or this ? void mylib_node_unset_value(mylib_node*); // or maybe this ? and all this cannot really be done without a dynamic allocation (which hopefully looks terrible to everyone), unless you fancy doing ugly ugly ugly stuff like struct mylib_node { char storage[sizeof c++ struct that was computed manually)]; }; so anything that'd allow other languages to understand at least C++ vocabulary would be a great boon in terms of perf, etc
- 6y ago
- pcr910303 6y agoRelated: There recently was a Twitter thread that you might be interested in: It's about the need for a new ABI which covers the middle ground of Rust, Swift, Zig, Nim, and other mid/low level languages, with lifetime annotations baked in so that the language can read them and manage memory without the need of developer's manual help.[0] [0]: https://twitter.com/bitshiftmask/status/1286411475658178561 https://twitter.com/bitshiftmask/status/1286411475658178561
- Someone 6y agoI think LLVM is too low level for accomplishing the goal of generating a Swift-like API for calling foreign code. Also, C, Objective-C and C++ cover a large part of the need (certainly when looking at Apple’s code base for their OS) I also think any other interoperability standard for native code that works well for a broad range of languages is a pipe dream. There simply are way too many language idioms. Even for managed runtimes, you get lots of friction, for example between languages with mutable state and languages without.
- flohofwoe 6y ago> I think LLVM is too low level for accomplishing... What I mean with "LLVM for language interoperability" is not using LLVM itself (although it could be part of the wider LLVM project), but the idea of LLVM. LLVM decoupled language frontends and code-generation backends by defining a common intermediate layer. Suddenly it was possible for individuals to create new languages that automatically run on all CPUs and ABIs supported by LLVM. What's missing for those small new languages is the same effect for connecting those languages to all the other languages that already exist. Doing this for each other language is impossible for small teams. Doing this for a single common interface specification on the other hand is fairly trivial. Such an "hourglass shape" would also make sense for language interoperability. But instead of having a common intermediate bytecode representation, have a common intermediate API-definition + ABI specification (somewhat similar to existing IDLs, but without a separate IDL-language that must be manually maintained, but instead automatically derived from the "native"-language interfaces. Also, it doesn't need nor should support all sorts of special language idioms, just a basic common set of "interface features". It would be very close to what we already have with the C API/ABI interoperability, just flavoured with additional annotations for some common higher-level concepts that languages have agreed on since C was invented (e.g. different types of references: unrestricted pointer, non-nullable pointer, ranged pointer, ownership annotations, etc...). Once you have such a common set of annotations, languages can create more idiomatic (not perfectly idiomatic) API bindings automatically. It doesn't have to be perfect, just an evolution of the current state (basically "rich C-APIs" instead of "plain C-APIs"). And plain old C would still be part of the language mix that's supported, it would just ignore most of the high-level annotations.
- saghm 6y ago> Wouldn't it be better to start working on an "LLVM for language interoperability"? That way every language only needs to provide a connection to an intermediate specification, and it can connect to any language supporting that same specification. My somewhat limited understanding is that the WASM interface types proposal is hoping to serve that sort of role. Note that in this case, the "web" part of "web assembly" is kind of a red herring; as I understand it, this proposal doesn't really have anything to do with the web and is more of an attempt to utilize WASM to create a sort of "universal ABI" that can replace the current de facto choice of using the C ABI everywhere.
- FuckButtons 6y agoit comes with some overhead though, which is useful in many circumstances as it also gives some sandboxing, but if your goal is universal interop then you probably want to have a solution that doesn’t incur a speed penalty.
- ianlevesque 6y agoWe could call it something like "Common Language Infrastructure" or COM maybe.
- AlexanderDhoore 6y agoShould I post the xkcd? Here goes: https://xkcd.com/927/ https://xkcd.com/927/
- deleted 6y ago[deleted]
- mpweiher 6y agoAnd then remember that Objective-C is, essentially, COM with language support.
- mlindner 6y agoUnfortunately COM was never OS independent so that kind of killed it off. It was also runtime instead of compile-time.
- pjmlp 6y agoWhy the past tense? COM is alive and well, being the way the large majority of Windows APIs get introduced since Vista. While COM is Windows specific, other implementations with similar ideas do exist. IBM and Unisys mainframe language environment, gRPC, D-Bus, XPCOM, SOM, Android IPC, Fuschia IPC.
- flohofwoe 6y agoIndeed, COM has some right ideas. There's just too much influence from the mid-90's OOP hype in it.
- estebank 6y agoIf you want to make a cross language protocol that most languages can support, OOP concepts will need to be first class citizens.
- smt1 6y agoyes, but specification has to "mean" something in some semantic way. If you understand some "deep" understanding of "meaning" to "vision" things to drop the "meaning=necessary" condition (this is according to modern kripean semantics in theory of computer science), you'll see that huge M:N matrix are just arbitrary meaning with implicit biased meaning that your experience can just mean non-linear-data that can just easily be reshaped using deformation theory or renormalization groups (common in modern day physics) to overload (modern mathmatical domain shifts between set thoeretic math to more organized category theory math) so you can just co-autocompute the co-monad of meaniningful using a applicative language (you get a rich frame as a set of un-sequences) or just think of arbitrary computations as bits using a convex optimization as compactifications in as arbitrary string theories in quantum field theory. Hint: One thing SIL has for it is a rich way to be an arbitrary bridge over arbitrary langs but those don't actually matter so much those are just arbitary combinatorial thinking. Much more powerful is to think allows big step small step semantics and whether arbitary straight line programs can be differenced or not. So thus if you understand thinks properly, it's better to just autoconvert that by overloading SIL using a first order substructural finite language like Rust where different modules give you Ocaml-like syntax but the borrow checker and type checker allows two "safe" locally lexical scopped ways of understanding how to reinvent those things to do free construction of work using modern math (hint: use constructive co-homologies) to create cast arb vector fields then make sure they are validated by good sound testing practices to a discrete encoding figure how how two arbitary associated classes of stuff that represent 2-transitive closures can be recombinated in a different weak linear 1-dimensional L-R module where very verbose but safe "local-global" laws can safely coexist where software hardware can interact at much analogies to antenna gain to transmux additon::multiplication n-hz to n^n^n polylog microprocessored:flipflops Remember = names = arbitary strutural pattern inferencing under right semantics might show you better ways of clearly thinking. but you'd have to basically understand some concept of inverse scattering theories and some generalization of arbitrary caclulus of differences and fluxions over some local. This is very important because wrong use of analog spectrum can hurt other beings. But digital spectra has theoretically infinite bandwidth if two cryptographic processes agree to the same cryptographic session they can do just do whatever and save "effort" work.
- sjwright 6y agoTo be fair though, for people developing for iOS it's a disproportionately huge point in the "huge M:N matrix". My experience is that grand solutions can be attractive in theory but awful in reality.
- a1369209993 6y ago> Wouldn't it be better to start working on an "LLVM for language interoperability"? > trying to create the "one universal language to rule them all" I feel this rebuttal of your proposal should be made, but I'm not sure how to articulate it more convincingly than you did.
- fluffy87 6y agoThat already exists, and it’s called the „platforms C ABI“. Every language that supports C FFI can talk with any other language that also supports it. All these other efforts are just really higher level wrappers around that, but given that there are a million tools for generating the glue code to bind APIs using C for most languages in use it is hard for me to see the value here.
- pjmlp 6y agoFor the platforms written in C.
- imtringued 6y agoNo, you're just wrong. What parent means is something like COM or GObject. The C ABI is too limited and still requires you to build things on top of it. It's kinda like saying all you need is bytes. From the perspective of the kernel this might be fine because it isn't supposed to prescribe a particular method but user processes must still agree on a character encoding or a protocol they are going to run on top of those bytes.
- dwaite 6y ago> That way every language only needs to provide a connection to an intermediate specification, and it can connect to any language supporting that same specification. The intermediate specification would be another language, so it would have the same impedance mismatch as the other N languages do. You have memory management issues, OOP inheritance issues, semantic differences. Just trying to do a interoperability layer for the different versions of character strings would be incredibly hard. Microsoft did something similar to this with CLI, but most people will note that JScript.Net and VB.Net are really new languages that just are optimized for porting Javascript and Visual Basic code over. They also defined a proprietary extension to C++ that allowed it to deal with managed objects so that it could interoperate with CLI code - but this did not aim to expose unmodified C++ code. Rather, it allowed you to use proprietary extensions to manually build bridges between the two.
- flohofwoe 6y ago> The intermediate specification would be another language, so it would have the same impedance mismatch as the other N languages do. Yes, but even though this is a limitation, every language only needs to care about connecting to this one intermediate "language". This is also why going through a C API already works quite well. Also it's interesting to note that Microsoft's latest version of the WinRT APIs are providing a standard C++17 wrapper on top of COM APIs and don't require C++ language extensions anymore.
- pjmlp 6y agoTo the anger of Windows devs being told to wait for ISO C++23 or even ISO C++26, hoping that the standard gets the relevant papers for C++/WinRT VS tooling to catch up with C++/CX from 2012. Right now it is hardly better than ATL/WRL, but so is life when Windows team wins its political battles with DevTools.
- 3jckd 6y agoWhile the assumption that you can make changes to swift’s stl is not that far-fetched, doing so to cpp’s is completely mental. I’ve got a feeling that swift is becoming a very polluted mashup of features that come from parties with conflicting interests. AFAIK, internally at Apple, teams pull in different directions (e.g. to get SwiftUI), at the same time there’s this half-baked differentiable programming / swift4tf manifesto, then there’s the backend swift initiative with vapour. This reminds of a hotch-potch that Scala’s framework and feature landscape is. The overhead of getting into it is quite substantial and for some, definitely not worth the investment if not just downright scary.
- jamil7 6y ago> I’ve got a feeling that swift is becoming a very polluted mashup of features that come from parties with conflicting interests. There some truth to that I guess, but I'd also add that a lot of these modern multiparadigm languages feel like they're converging feature-wise (with a few outliers). I feel like Swift still has a unique enough feel to it and I enjoy working with it a lot. I think Chris Lattner has also expressed some concern about the focus on features over everything else.
- skohan 6y agoYeah also having worked more with Rust, it seems that a lot of the features added to Swift recently could be covered by decent meta-programming support. That said, automatic differentiation could be a game-changer and should absolutely be included in the core language.
- layoutIfNeeded 6y agoAD in the core language? Why? Automatic differentiation would be prime candidate to be implemented as a metaprogramming library.
- Someone 6y agoThe choice may have been made because Swift doesn’t support meta programming well enough to do it well purely in a library. The plan they have/had (https://github.com/apple/swift/blob/main/docs/DifferentiableProgramming.md https://github.com/apple/swift/blob/main/docs/Differentiable...) claims “First-class language support for differentiation will enable convenient, extensible, and performant differentiable programming in Swift - more so than library-based approaches”.
- humanrebar 6y agoWhen interoperating between languages, there are several things to consider: - API - ABI, including threading, exception, function call, and memory models at the ABI level - build specification - packaging This article mostly focuses on API, there seem to be some nods to the other three, but those seem like the harder and more pernicious problems to me. For instance, how would the build system know that a library is being included that requires the swift runtime? Or even the C++ runtime. If any library was built against a different set of standard library interfaces (of any language), do any tools fail with a useful diagnostic? That's not to say this isn't helpful research, but there's a lot of work to do before all of this is robust enough to be straightforward for end users.
- oscargrouch 6y agoThis is only being talked about now, because ABI compability is already working. The Swift compiler is in C++ targeting the LLVM and therefore with great interoperability with C and C++ through Clang. The Swift compiler also ships with Clang, and you can link C and C++ projects that are dependencies of Swift packages using the Swift package manager with little effort.
- humanrebar 6y agoIf only having tools from the same toolchain guaranteed ABI compatibility worked! Something as apparently benign as using absl::string_view with different '-std=c++NN' flags in different otherwise unrelated C++ libraries is an ABI break.
- kkarakk 6y agoDoes swift work 1:1 on windows or linux yet?
- AlchemistCamp 6y agoI was recently surprised to find that it's not even possible to search for C++ on Apple's developer docs. When you try to, it replaces C++ with C. https://developer.apple.com/search/?q=c%2B%2B https://developer.apple.com/search/?q=c%2B%2B
- formerly_proven 6y agoThis is a bug in their app, because it incorrectly canonicalizes %2B to + then + to space and then removes leading/trailing spaces.
- racnela 6y agoI thought it would be worth mentioning this relatively new, little known, open source project, called gluecodium: https://github.com/heremaps/gluecodium https://github.com/heremaps/gluecodium.