[HN Gopher] Swift and C++ interoperability workgroup announcement
       ___________________________________________________________________
        
       Swift and C++ interoperability workgroup announcement
        
       Author : pjmlp
       Score  : 110 points
       Date   : 2022-02-01 09:54 UTC (13 hours ago)
        
 (HTM) web link (forums.swift.org)
 (TXT) w3m dump (forums.swift.org)
        
       | dureuill wrote:
       | Great, now I want the same for Rust <-> C++
        
         | lowbloodsugar wrote:
         | Funny, my cynical brain read the Swift/C++ announcement as two
         | dead languages fighting for relevance, in the face of Rust, by
         | banding together. Fuck Rust <-> C++. Let C++ die! ;-) (only
         | half joking)
        
           | pjmlp wrote:
           | So when is Apple going to rewrite IO and Driver Kit, and re-
           | base Metal Shading Language in Rust?
           | 
           | If C++ dies Rust will have a hard time replacing its GCV/LLVM
           | backends.
           | 
           | Cranelift as it stands today won't do it.
        
             | estebank wrote:
             | >> Let C++ die!
             | 
             | > So when is Apple going to rewrite IO and Driver Kit, and
             | re-base Metal Shading Language in Rust?
             | 
             | Death of a language isn't a clear cut thing that really
             | happens, so everyone has their own definition. Some
             | consider a language dead when they fall from former glory,
             | so for a popular language they don't need to disappear,
             | they can even have multiple thriving niches and still be
             | considered "dead" because they are a portion of the usage
             | they used to have (see Python 2, still widely in use, but I
             | can make argument to call it "dead"). Others consider a
             | language dead when direct competitors are used instead of
             | them for new projects (see Perl). Yet others consider a
             | language dead when there's an active and thriving effort to
             | migrate existing applications to other languages. All of
             | these are varying interpretations of "dead language". I
             | would call Delphi, Perl, Python 2 "dead", yet there are
             | plenty of projects in use out there written in those
             | languages, and in some cases even thriving communities. But
             | even if their absolute numbers don't decrease, the rest of
             | the world might continue to out grow them into
             | "irrelevance" (whatever one might want to consider that to
             | be).
             | 
             | All that to say: C++ doesn't need to _disappear_ to  "die",
             | it doesn't need to die for other langs to thrive, and it
             | doesn't need to "die" _even_ if other languages thrive. It
             | is not a zero-sum game.
             | 
             | > If C++ dies Rust will have a hard time replacing its
             | GCV/LLVM backends.
             | 
             | > Cranelift as it stands today won't do it.
             | 
             | You're comparing a 20 year old project (LLVM) with a 4 year
             | old project (cranelift) that have different goals. It's
             | like comparing Rust and Python, or Fiat and Cannondale:
             | they have some similarities, but any comparison is gonna be
             | stretched beyond use.
        
               | pjmlp wrote:
               | Well, most Rust vs C++ comments, like the one I was
               | replying to, tend to lack a perspective of what the
               | market actually uses, and how Rust is dependent on C++
               | toolchains (at least for now), so.
        
             | tialaramex wrote:
             | LLVM in Rust seems actually plausible, there are some Rust
             | ideas that probably feel very natural indeed to LLVM core
             | people, in particular as I understand it the niche trick,
             | where Rust knows the valid bits for type A and type B don't
             | overlap, so, it can fit them both in whichever was the
             | largest (e.g. Option<NonZeroUsize>), is something LLVM does
             | a _lot_ in its own internals.
        
               | pjmlp wrote:
               | The problem isn't the language, rather the volume of
               | contributions.
               | 
               | Last year, LLVM has reached Linux kernel level of
               | contributions from researchers and compiler vendors.
               | 
               | LLVM in Rust won't have that, and no one is going to
               | rewrite such a massive compiler building infrastructure.
               | 
               | Then we have all the companies that building tooling on
               | top of it, and everything related to the development
               | process that relies on how LLVM is implemented.
        
           | HNSucksAss wrote:
        
         | LegionMammal978 wrote:
         | I've asked around a bit, and so far I've found no language or
         | tool that can directly access C++ libraries without manually
         | writing bindings. I hope that can change sometime in the near
         | future.
        
           | gavinray wrote:
           | I know of two languages:
           | 
           | 1. D (https://dlang.org/spec/cpp_interface.html)
           | 
           | 2. Nim. Though this is a bit cheap because Nim is a frontend
           | to C(++), so you're really writing C++ that calls other C++
           | when it boils down to it. See https://nim-
           | lang.org/docs/manual.html#implementation-specifi...
        
           | pzo wrote:
           | There is one -> Objective-C++ - interop is very seamless
           | (just change file extension from .m to .mm). I do hope as
           | well that will change and we will see some other languages
           | speaking to c++ so easily.
        
         | torquemodwanted wrote:
         | Not a working group, but a library does exist: https://cxx.rs/
        
           | rvz wrote:
           | I hope one does not need to write the signatures manually and
           | tweak the cxx generator, for detecting flags, types and the
           | like just to get it properly working. If that's the case,
           | then that would be tons of maintenance and more trouble than
           | its worth for a more complex C++ codebase.
           | 
           | Best to make that a first party feature built into the
           | language compiler and have it do the majority of the work
           | automatically rather than manually define the C++ types,
           | functions, etc using a third party library.
        
           | dljsjr wrote:
           | The difference is that cxx is doing codegen to create a C ABI
           | compatible bridge. So the same thing most people already do
           | when they want to interact w/ C++ over FFI.
           | 
           | I _believe_ that TFA is actually saying that the Swift
           | compiler speaks C++ directly without doing any codegen and
           | just handles everything at the compilation level. Same end
           | result but a lot of subtle differences. Not having to do
           | codegen is a big win, especially in Rust where compile times
           | aren 't terrific and binary sizes can already bloat up due to
           | the statically linked nature.
        
       | The_rationalist wrote:
       | Or you know, just use GraalVM
        
         | olliej wrote:
         | I did a quick check and graalvm doesn't appear to support swift
         | or c++, so I'm not sure why you're suggesting it?
        
       | cdcarter wrote:
       | I've been spending the last couple weekends porting Thorsten
       | Ball's Monkey language (from the texts Writing an Interpreter in
       | Go and Writing a Compiler in Go) to Swift. A year ago I spent a
       | few weeks playing with Swift on the server but never really made
       | anything happen with it, so this has been my real nuts and bolts
       | introduction to the language.
       | 
       | I found it to be pretty neat, but it's very difficult to
       | determine whats allowed to use outside the Apple ecosystem. The
       | documentation is sporadic and there is only a reference manual.
       | It makes me long for the Rust Book, with its tutorial style
       | introductions. There are of course plenty of Swift tutorials out
       | there, but they expect 1) you want to write an iOS App, and 2)
       | you've never programmed a day in your life before.
       | 
       | The "standard library ecosystem" is very confusing. There's the
       | actual language standard library, which is much like "core" in
       | Rust. Then there's Apple's "Foundation" library, which is the
       | more "batteries included" type standard library most people look
       | for in a language. But "Foundation" isn't... straightfoward to
       | understand. First of all, there's two completely separate
       | implementations. On Apple platforms, you get the real Foundation,
       | implemented in Objective-C with no source code available. On
       | Linux, you get "swift-corelibs-foundation", which is fully open
       | source and written entirely in Swift (really nice to look up what
       | it is actually doing).
       | 
       | But swift-corelibs-foundation has a lot of missing features. To
       | figure out if you're allowed to use something, you better be
       | ready to look up the source code and see if its actually
       | implemented on the Linux version. Or study a very long
       | complicated markdown table in the github repo where they track
       | what they've ported.
       | 
       | Want to develop on your MacBook but deploy to Linux? Better set
       | up a complicated Docker environment so that you can actually see
       | how your code will run with swift-corelibs-foundation. You
       | _can't_ import or build against it on Apple platforms.
       | 
       | A lot of people learn a programming language by spending a lot of
       | time reading the standard library. Well, it's nice that swift-
       | corelibs-foundation is open source and publicly accessible and
       | written in Swift. Unfortunately, it's not a great place to learn
       | swift. Since it's a reimplementation of Foundation, which is
       | itself a port of the Objective-C "Foundation Kit" library, its
       | full of non-swifty concepts and ideas. There are, MOSTLY, more
       | Swifty method implementations hanging off of the Foundation
       | types, but there are also countless bits of API that take unsafe
       | pointers or are fully deprecated and you must learn to ignore
       | (looking at you, NSZone).
       | 
       | Learning Foundation is no easy task either. You can read the
       | swift-corelibs-foundation source, of course. But since it's
       | Swift, types are frequently re-opened and extended in other files
       | so there's no one place to view the entirety of a type. There are
       | the Apple developer docs, but theres no location where they list
       | all the types in Foundation, or all the methods/properties on a
       | type. The docs are handwritten, not generated from comments in
       | the code. Apple recently released "DocC" to generate docs from
       | swift libraries, so I'm hoping this one changes soon. There's the
       | venerable swiftdoc.org which has generated documentation, but it
       | only covers that "core" standard library. Also, certain symbols
       | constantly 404 on it.
       | 
       | Thankfully, implementing a simple bytecode compiler doesn't
       | require much beyond the standard library types. I still
       | occasionally have to import Foundation, but its mostly just to
       | get a single method here or there on a stdlib type, not to use
       | some complicated NSObject based "class cluster".
       | 
       | I'm hopeful that good interop frameworks drive more folks to use
       | the language outside Apple platforms, and real investment gets
       | put into these issues. Don't get me started on XCTest on linux...
        
       | ChubbyGlasses wrote:
       | This is really nice to see; apart from the weirdly named, macOS
       | specific NS* apis, Swift has been a real pleasure to use and,
       | refreshingly, feels like a language designed for humans first. I
       | hope this means Swift has a chance to eat Rusts' lunch :)
       | 
       | Does anyone know how c++ classes and struct will interact with
       | ARC?
        
         | tarentel wrote:
         | > _The biggest semantic impedance mismatch between C++ classes
         | and Swift classes is that Swift classes are reference-counted.
         | It is certainly possible to import a C++ class as a Swift class
         | if it is intrusively reference counted, or wrapped in a
         | shared_ptr._
         | 
         | > _But what about non-movable C++ classes that are not
         | reference counted? This issue could be worked around by making
         | retain and release operations on C++ classes be a no-op, and
         | introducing an explicit "delete" operation, effectively making
         | C++ class references in Swift equivalent to
         | UnsafeMutablePointer._
         | 
         | There's some information about it in
         | https://github.com/apple/swift/blob/main/docs/CppInteroperab...
         | this is quite long though so there's likely a lot more
         | information. This quote is apparently just one strategy they're
         | considering? At least that's my take on reading it.
        
         | lubesGordi wrote:
         | NS stands for NextStep.
        
           | [deleted]
        
       | jb1991 wrote:
       | Surprised to read that the compiler already supports some C++
       | types? That's news to me. It's not clear to me if that's already
       | in the shipping compiler or in some other version or just a
       | proposal.
        
         | gavinray wrote:
         | Yes, it has been in the Swift compiler for some time now
         | 
         | The original flag was "-experimental-cxx-interop", now it is
         | "-enable-cxx-interop"
         | 
         | See here for examples of it in use, including interop with the
         | C++ std library types:
         | 
         | https://github.com/plotfi/cxx-interop-test
        
         | beached_whale wrote:
         | Right, a C interface without obj-c would be enough to make it
         | much easier
        
           | jb1991 wrote:
           | I already use C interfaces on C++ code to interact directly
           | with Swift without objectiveC. What I'm curious about is if I
           | can actually stop doing even that for many common types? It
           | appears the compiler supposedly already supports that.
        
             | beached_whale wrote:
             | I didn't know even that was possible and thought that I had
             | to use objc as it used to be. Nice
        
               | conradev wrote:
               | You can also use this to wedge the C preprocessor into
               | Swift
               | 
               | for example, I can inject variables into the C
               | preprocessor in my build settings and have a C header
               | that defines constant strings with those variables, which
               | I can then import directly into Swift as a module
        
               | user-the-name wrote:
               | Objective-C is a superset of C. If there is Objective-C
               | interop, there is by necessity already C interop.
        
               | BBC-vs-neolibs wrote:
        
               | gumby wrote:
               | That is not completely true. There could be object round
               | trip support between objective c and swift objects which
               | would not be available through a C interface. Consider
               | ObjectiveC++ as an example.
        
               | jb1991 wrote:
               | You are talking about something different, I think. Of
               | course, if you need Objective-C features, you don't get
               | those from C. But if you simply need C features, you
               | don't need Objective-C just for that. In the context of a
               | C api exposed over C++, objective C is not necessary.
        
             | grayprog wrote:
             | How do you create the C interfaces from C++ code?
        
               | jb1991 wrote:
               | I'm not sure exactly what you're asking, but it's just
               | basically writing a C header file as an API, but the
               | implementation is in a source file that is in C++.
        
               | grayprog wrote:
               | I see, so you're just writing the bridge code yourself.
               | OK, I do the same in Objective-C++, so at least it gives
               | me an object-based interface, as well. But saving this
               | step and having a direct Swift <-> C++ would be helpful.
        
               | jb1991 wrote:
               | Yeah for me it's just about keeping Obj-C out of the
               | project. It's enough to have two languages, I don't want
               | to unnecessarily add a third.
        
               | Tyr42 wrote:
               | I mean, you also have to be careful to return pointers
               | and not smart pointers and so on. It can be a bunch of
               | work if you need to write a bunch of freestanding
               | functions to wrap the c++ object methods.
        
               | jb1991 wrote:
               | Well, you won't return smart pointers if your header file
               | is in fact a C API, since smart pointers are C++ only.
               | 
               | It's usually as simple as calling data() on a vector or
               | std::string (as well as having a function to return the
               | length or size of the data buffer). And if you wrap your
               | header file in the normal C externs, it shouldn't compile
               | if you do things that are not allowed in C, if I
               | remember.
               | 
               | But you are right it can be a lot of work if you have a
               | large surface area. I try to stick to tight, focused
               | APIs, and data is normal C structs which work fine in C++
               | as well.
        
       | sremani wrote:
       | Slightly side question -- does this bi-directional
       | interoperability improve Swift adoption to multiple platforms.
       | Swift when it was released had much fanfare and definitely looked
       | like a balanced language but as time passed has been limited to
       | Apple eco-system.
        
         | jb1991 wrote:
         | Swift has always directly interacted with C, so I doubt limited
         | support for C++ would make a huge difference in that kind of
         | adoption.
        
           | physicsguy wrote:
           | Plus C++ devs often expose a C interface because most
           | languages support that.
        
       | cortexio wrote:
        
       | sirwhinesalot wrote:
       | I wish them the best, but getting two of the most complicated
       | languages available today with widely different semantics talking
       | to each other is going to be a tall order.
       | 
       | I wish they'd start by standardizing something equivalent to
       | "extern C" in Swift, so other languages can consume (wrapped)
       | Swift libraries without having to implement support for the
       | rather complicated Swift ABI.
        
         | estebank wrote:
         | I think there's space for a high-level ABI that specifies
         | little more than C + VTables + callback register (and
         | optionally ownership information, even if ignored by the caller
         | or host) that _multiple_ languages could decide to use for
         | interop. COM already exists and its a shame that it
         | simultaneously does too much and too little to aid in safely
         | exposing APIs, but I would love to see its ideas pushed
         | further.
        
           | sirwhinesalot wrote:
           | I've discussed a similar concern in another hackernews post,
           | though there I suggested improvements to the C language
           | itself since it's the one standard everyone is somewhat
           | forced to follow.
           | 
           | The problem with such an ABI is getting people to use it,
           | there's no single entity with enough power to enforce it.
           | 
           | I've thought of tackling the problem in another direction,
           | making a simple C-like language (but slightly higher level)
           | which uses the C ABI but with proper support for
           | slices/strings/interfaces/errors/etc. _and_ automatically
           | produces wrapper code for mainstream languages (C++, Java,
           | C#, Swift).
           | 
           | The wrappers wouldn't be idiomatic code in the host language,
           | but they'd be directly usable, whereas right now wrapping a
           | "C" library (even when produced by a higher level language)
           | requires recovering all of the semantic information in an
           | additional, library-dependent high-level wrapper.
           | 
           | For example, some SMT solvers expose quite nice C APIs, but
           | to use them in say... Python, you'd need to use ctypes and a
           | lot of low level code, which is why they go out of their way
           | to expose wrapper APIs.
           | 
           | Some solvers like Yices2 have really low level Python
           | wrappers, which mostly take care of the memory management,
           | unpacking lists into a pointer and a length, and string
           | conversions. There's no reason that couldn't be automated
           | with a slightly higher-level than C language.
        
             | estebank wrote:
             | Focusing on the "you have now N + 1 standards" problem, I
             | think following the Language Server strategy is the way to
             | go: you don't _force_ people to support it, you focus on
             | specifying an API that support a handful of representative
             | bridges (let 's say Python <-> Swift <-> Java <-> Haskell),
             | with a builtin method to evolve and then let people realize
             | that supporting this new ABI immediately brings support for
             | every other language that supports it in an idiomatic-ish
             | way.
        
               | sirwhinesalot wrote:
               | Yes, the wrapper generators would not be built into the
               | compiler, they're just little pieces of software that
               | generate the relevant code (anyone could develop one in
               | their own language in a couple of days).
               | 
               | The language exists merely as a way of directly
               | interfacing with the ABI, a way to get the libraries out
               | the door so interest in the ABI exists (same as how
               | VSCode made LSP popular).
               | 
               | The problem with doing Python <-> Swift is that you
               | cannot (and should not) try to expose the entirety of
               | Python and Swift to either side. So you need an "extern
               | ABI" solution to expose your Swift code, except this is
               | not built in to the Swift compiler so now you are in
               | trouble.
               | 
               | If you go the external route you end up with SWIG, which
               | is something you only use when you have no other option
               | (CVC4 moved away from it for example).
               | 
               | Having a language that directly supports the ABI
               | sidesteps this issue. All code written in the language
               | works with the ABI directly so you get the wrappers for
               | free without thinking about how to implement them. A lot
               | of libraries are written in C directly for this very
               | reason!
               | 
               | Once it becomes popular enough, languages would implement
               | "extern ABI" directly, and can now talk to each other
               | over it without the middleman. Same as how a compiler
               | with LSP support can be used in editors that are not
               | VSCode.
        
         | favorited wrote:
         | > I wish they'd start by standardizing something equivalent to
         | "extern C" in Swift
         | 
         | There is the unofficial (but very relied upon) @_cdecl, if
         | you're OK with needing to update your code if/when that
         | eventually gets standardized. That attribute will take care of
         | the calling convention difference for you.
         | 
         | https://github.com/apple/swift/blob/main/docs/ReferenceGuide...
        
       | zoecarver wrote:
       | Hello HN! C++ interop is a project I've been working on for a
       | year and a half now, so you have no idea how cool it is to see
       | this on the front page. Really made my day. Anyway, there are
       | some really great questions in this thread (and some slight mis-
       | understandings), if you want your questions answered, feel free
       | to post them as a reply to the announcement on the Swift forums
       | (linked above). I'd be happy to answer them :)
       | 
       | (To keep things organized, it would be great to have all the Q&A
       | happen in one place, that's why I'm asking you post it in the
       | forums. And remember, every question is valid, so don't be shy!)
        
         | bitigchi wrote:
         | Thanks for all the work! When do you think it would be
         | production ready?
        
       | sarunas wrote:
       | This will be useful for Swift for backend applications as this
       | can open up use of C++ libs (in case native is lacking).
       | 
       | Anyone using Swift for high load production workloads yet?
        
       ___________________________________________________________________
       (page generated 2022-02-01 23:02 UTC)