[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)