[HN Gopher] Mixing Swift and C++
       ___________________________________________________________________
        
       Mixing Swift and C++
        
       Author : oumua_don17
       Score  : 76 points
       Date   : 2023-07-23 14:04 UTC (8 hours ago)
        
 (HTM) web link (www.swift.org)
 (TXT) w3m dump (www.swift.org)
        
       | chunkyguy wrote:
       | > A C++ class or structure becomes a standalone type in Swift.
       | Its relationship with base C++ classes is not preserved in Swift.
       | 
       | C++ `class Fern: public Plant` becomes two different types in
       | Swift `struct Plant` and `struct Fern`, how is this supposed to
       | help anyone?
       | 
       | https://www.swift.org/documentation/cxx-interop/#accessing-i...
        
         | dagmx wrote:
         | It still allows you to use them for interop. The only
         | functionality that would be impaired is checking for
         | inheritance with an `as?` type check/conform.
        
           | fooker wrote:
           | No, this blocks a fundamental concept of OOP: Liskov
           | Substitution Principle.
           | 
           | The idea is that you should be able to use a derived object
           | anywhere the base one is required.
        
             | dagmx wrote:
             | It impairs that principle, yes. But it doesn't block
             | similar patterns that give you similar end results. Swift
             | has very flexible generics programming and type abstraction
             | that still lets you use it with a little extra work.
             | 
             | Yes, it won't be as ergonomic as the ideal, but it's better
             | than many binding solutions from C++ to compiled languages,
             | while providing most of the usability.
             | 
             | Plus the footnote says that they plan to resolve this in
             | future Swift versions.
        
             | dwaite wrote:
             | It does not import the relationship, but you can still
             | model it via protocols.
        
         | mgaunard wrote:
         | Interop isn't magic. It can't make the C++ model transparently
         | compatible with that of Swift when the two languages deviate.
        
       | kubb wrote:
       | C++ interop is impressive, and notoriously hard to get right.
       | This seems like it would be able to cover a lot of APIs.
       | 
       | Swift and C# are the well-designed languages I'd rather use at my
       | work instead of Go. It's a real shame both are effectively locked
       | into a specific platform.
       | 
       | You can really tell that they had years of attention and careful
       | design by experts in PL poured into them. Go seems like an
       | amateur hobby project in comparison.
        
         | metaltyphoon wrote:
         | >It's a real shame both are effectively locked into a specific
         | platform.
         | 
         | This view of C# will be wrong for a almost a decade very soon!
         | (if you don't count mono)
        
         | wilg wrote:
         | I'm not sure why you're saying Swift is locked in to Apple
         | platforms, it's definitely cross-platform. It's no problem to
         | run Swift on Linux or Windows. Of course, Apple's UI libraries
         | aren't cross-platform. And they're putting a bunch of effort
         | into making it better for servers and such. I wish more people
         | realized how usable it is cross-platform, I think this is a
         | misconception that hampers Swift adoption.
         | 
         | Swift is definitely my favorite programming language from a
         | language standpoint. I really like the way Swift works. It's
         | safe, concise without being terse, and easy to extend.
         | 
         | Sure, some people can argue there's some "bloat", but I think
         | that's inevitable in a language that was designed to
         | immediately be usable within Apple's existing APIs and
         | frameworks. There's going to be complexity with Objective-C
         | interop, C++ interop, etc. But that stuff is necessary for
         | Swift to be usable for big projects. And I think Apple has done
         | quite a good job of evolving Swift to be cleaner, clearer, more
         | ergonomic, etc.
         | 
         | I'm very excited that there's a lot of effort behind an open-
         | source, cross-platform type-safe, compiled language that also
         | prioritizes ergonomic high-level programming.
        
           | SubjectToChange wrote:
           | I don't trust Apple to care about platforms or developers
           | that aren't directly benefiting them.
        
             | duped wrote:
             | They barely care about developers for their own platforms.
             | Their docs are atrocious.
        
           | t0ps0il wrote:
           | > I'm not sure why you're saying Swift is locked in to Apple
           | platforms, it's definitely cross-platform
           | 
           | I think the key word in OPs comment is "effectively".
           | 
           | The tools for building cross platform Swift exist and work in
           | various levels but they aren't at the point where you would
           | want to choose Swift over existing cross platform tools.
        
         | coryrc wrote:
         | IMO Go would have been 70% better with Result instead of
         | (*type, error). So, so much duplicative code would have been
         | avoided. It's not even a different paradigm. What a wasted
         | opportunity.
        
         | tempodox wrote:
         | I'm using F# via the .NET SDK on macOS (i.e. I could also use
         | C#), so it seems to have less platform lock-in than Swift at
         | this point. It does have its limitations, for instance I can't
         | for the life of me figure out how to make the F# REPL
         | UTF8-capable. As ludicrous as that is, it's not really my use
         | case, so I can live with that for now.
        
         | bsaul wrote:
         | Currently developing both in swift and go and i have the exact
         | inverse feeling.
         | 
         | Go seems to have been developped by true masters that really
         | understand that less is more. They've also kept a laser sharp
         | focus on working on things that really matters and took the
         | time to do things right.
         | 
         | Swift on the other hand looks like more and more bloated every
         | day, without adressing the main pain points of the experience
         | of coding in swift in the real world.
        
           | SubjectToChange wrote:
           | _Go seems to have been developped by true masters that really
           | understand that less is more._
           | 
           | "The key point here is our programmers are Googlers, they're
           | not researchers. They're typically, fairly young, fresh out
           | of school, probably learned Java, maybe learned C or C++,
           | probably learned Python. They're not capable of understanding
           | a brilliant language but we want to use them to build good
           | software. So, the language that we give them has to be easy
           | for them to understand and easy to adopt." - Rob Pike
           | 
           | Ignoring complexity on the language level simply passes the
           | buck to application code, and developers end up paying that
           | price across the ecosystem in perpetuity.
           | 
           |  _They 've also kept a laser sharp focus on working on things
           | that really matters and took the time to do things right._
           | 
           | Go's async model is underspecified, its implementation of
           | generics incurs runtime overhead, much of the "wonderful
           | tooling" only exists because of severe shortcomings in the
           | language design and/or compiler implementation, its FFI is...
           | difficult, etc.
           | 
           | To be blunt, the values that Go embraces are none of the
           | values I seek in a programming language or community. And I
           | feel sorry for anyone too heavily invested in Go to turn
           | back.
        
             | bsaul wrote:
             | golang concurrent programming is by far the best i've ever
             | used _for its application domain_ which is mainly
             | infrastructure middlewares running in a connected
             | environment.
             | 
             | The tradeof between language features and maintainability
             | is also IMHO the best in class. Never before have i ever
             | looked at a stdlib sourcecode and told myself "hu, yeah i
             | see how that works".
        
           | saagarjha wrote:
           | Depends on what you think they're masters of. Developer
           | experience? Sure. Modern programming languages design?
           | Absolutely not.
        
             | ori_b wrote:
             | What is the purpose of modern language design, if not to
             | improve developer experience?
        
               | saagarjha wrote:
               | Developer experience is just one facet of writing
               | software. It means that it is pleasant to write code, but
               | you can also focus on:
               | 
               | * Language features that make it so that you don't have
               | to write code at all
               | 
               | * Tooling that makes it easier to find bugs in the code
               | you do write
               | 
               | * Expressiveness and portability that allows the code to
               | be used in more places
               | 
               | * Approachability, so that new people can pick up the
               | language quickly
               | 
               | * "Batteries", so that people can rely on your high-
               | quality libraries instead of having to manage their own
               | 
               | * Documentation and community, to handle the hardest
               | parts of programming: people
               | 
               | * Performance, so that the code can use fewer resources
               | 
               | ...among many other things.
        
               | jb1991 wrote:
               | It's a subjective issue, but sometimes the end results
               | can be better even if the experience of getting there is
               | not as nice as a simpler language that is more bug-prone.
               | Consider Rust, which is notoriously difficult to learn,
               | but that offers improved end results in many cases re:
               | security, safety, reliability.
        
               | ori_b wrote:
               | Can you explain how that's not an aspect of developer
               | experience? It seems to be like trading off between type
               | system correctness (you can go all the way to needing
               | full formal proofs of correctness, resource use, etc) and
               | ease of getting stuff done is the core of developer
               | experience.
        
               | worik wrote:
               | With Rust it is the learning curve that is hard.
               | 
               | I find every other aspect of "developer experience"
               | excellent
        
               | jb1991 wrote:
               | Does your idea of a good developer experience include
               | programs that are reliable, won't crash in production,
               | won't be compromised, and save you lots of time later on
               | so you can just focus on writing code the first time? In
               | the absence of these guarantees, your developer
               | experience can include some very frustrating and/or
               | stressful debugging.
        
               | ori_b wrote:
               | Yes. Does yours not?
               | 
               | Tools like Agda, Spark, Idris, and Coq move the tradeoff
               | around towards "probably correct", and I welcome seeing
               | some of their features become gradually available.
               | Getting things right the first time is useful.
               | 
               | But these features can also make it hard to get anything
               | done quickly.
               | 
               | Good developer experience means finding a balance between
               | the quick and dirty, and the provably correct.
        
               | jb1991 wrote:
               | You just made my point for me.
        
               | geodel wrote:
               | Same as purpose of modern arts. True masters know its
               | worth. Will it look good in my living room? Doesn't
               | matter.
        
             | tempodox wrote:
             | I think Go is made for writing a certain kind of software
             | that is important for Google, and for a certain kind of
             | developer Google wants to have writing this software. That
             | the result is not the kind of language I would want to use
             | is immaterial. I'm quite sure Go is masterfully targeted
             | for the purposes Google wants it for.
        
               | pjmlp wrote:
               | Go was designed by a couple of well known UNIX folks that
               | dislike C++.
               | 
               | With exception of Kubernetes, most of Google's software
               | keeps being written in Java, C++, Kotlin, and nowadays
               | Rust.
               | 
               | Its use is much more widespread outside Mountain View
               | walls than inside them.
        
               | seabrookmx wrote:
               | And remember that unlike Amazon does with AWS, Google
               | doesn't use GCP/Kubernetes to run it's infrastructure.
               | 
               | Google's software runs on Borg, which is _not_ written in
               | GoLang.
               | 
               | Google's three OS projects all eschew GoLang as well.
        
             | Someone wrote:
             | But developer experience is a factor that should weigh
             | heavily in evaluating the quality of a programming
             | language.
             | 
             | I also fear Swift is going a step too far. For example, IMO
             | Swift's compilation speed isn't good enough.
             | 
             | If that's a matter of lack of tooling, I won't blame the
             | language, but is it, or is its slowness unavoidable for a
             | language that is so flexible? If the latter, I would rather
             | have a bit less flexibility and more compilation speed.
             | 
             | Similarly, there's quality of error messages. Swift has
             | gotten better there, but still has some weird ones. Are
             | they unavoidable for the current language?
        
               | cvwright wrote:
               | I would be fine with slow, if the Swift compiler could
               | actually compile all valid Swift programs. It's pretty
               | commonplace for me to have to break a large or
               | complicated function into smaller bite-size pieces
               | because the compiler can't type check it all at once.
        
               | refulgentis wrote:
               | I had several years in the ObjC ecosystem, embraced Swift
               | whole-heartedly immediately at 1.0, and was surprised by
               | people nitpicking like this.
               | 
               | It's been humbling to come back to it over the
               | intervening 7 years and realize they weren't nitpicks
               | that would be resolved shortly, and people would
               | understand if they just read the swift-evolution mailing
               | list. They were fundamental flaws.
        
               | novok wrote:
               | If they removed the few small features that are
               | responsible for 80% of the slowness and called it
               | optimized swift I bet many would embrace it fairly
               | quickly, especially considering they are functionally
               | cosmetic features.
        
               | math_dandy wrote:
               | When will "Swift: The Good Parts" be available for
               | preorder?
        
               | saagarjha wrote:
               | Not really. These are pretty critical features for the
               | language.
        
               | refulgentis wrote:
               | Not type inference, rather, whatever is so pathological
               | about the fundamental algorithm for doing Swift type
               | inference that it can become an infinite loop.
               | 
               | This is a Swift-only feature in major languages with type
               | inference.
        
               | newZWhoDis wrote:
               | If you are writing functions that the current/latest
               | Swift compiler can't handle on modern hardware then I
               | feel sorry for anyone who has to someday read your code.
        
               | bsaul wrote:
               | just try using state machines modelled with enums and
               | you'll fairly quickly reach those limits.
        
               | jwells89 wrote:
               | This used to irritate me, but now that I'm in the habit
               | of breaking functions up I've come to prefer it. It makes
               | for code that's easier for myself to read and follow
               | further down the road, which I think is a reasonable
               | proxy for readability by others.
        
               | cachvico wrote:
               | Writing modular code is good but that's a ridiculous
               | reason to need to do so.
               | 
               | Xcode also trips on simple type errors and sometimes
               | fails to even provide a line number where the error lies.
               | As someone who just wrote a Swift app after no prior
               | exposure, it's oddly immature in some basic ways after
               | nearly a decade from launch.
        
               | jwells89 wrote:
               | Yeah I won't defend it too much, Xcode/SourceKit/etc are
               | clearly written in a way that assumes devs are writing
               | perfectly idiomatic, smell-free code which isn't very
               | aligned with reality. I've more or less got a feel for
               | what makes it grumpy so I don't trip it up too often any
               | more but it's annoying on the odd occasion I do.
        
               | dagmx wrote:
               | When discussing compiler speed, Go specifically
               | prioritizes compilation speed over optimization of the
               | resulting code.
               | 
               | Swift and Rust both suffer from slower compilation than
               | Go, primarily because LLVM prioritizes optimization over
               | speed.
               | 
               | There are of course other reasons like complexity of
               | language, size of compilation units etc... but
               | optimization tends to be the biggest hit in my
               | experience.
               | 
               | Hence why Rust is adopting/investigating cranelift as a
               | debug compiler to improve speed.
        
               | Someone wrote:
               | > There are of course other reasons like complexity of
               | language, size of compilation units etc... but
               | optimization tends to be the biggest hit in my
               | experience.
               | 
               | I _guess_ you don't have much experience with Swift. LLVM
               | code generation may be slower than alternatives, but
               | that's more or less by a constant factor.
               | 
               | Swift's type inference, on the other hand, can lead to a
               | combinatorial explosion.
               | 
               | For example,
               | https://www.hackingwithswift.com/articles/11/how-to-make-
               | swi... claims that                 let sum = [1, 2,
               | 3].map {         String($0)       }.flatMap {
               | Int($0)       }.reduce(0, +)
               | 
               | takes over 11 seconds to compile, while
               | 
               | compare this code:                 let sum = [1, 2,
               | 3].map { (num: Int) -> String in         String(num)
               | }.flatMap { (str: String) -> Int? in         Int(str)
               | }.reduce(0, +)
               | 
               | takes about 75ms, and                 let numbers = [1,
               | 2, 3]       let stringNumbers = numbers.map {
               | String($0)       }       let intNumbers =
               | stringNumbers.flatMap {         Int($0)       }       let
               | sum = intNumbers.reduce(0, +)
               | 
               | compiles in 71ms.
               | 
               | Of course, all of these use LLVM, and likely even
               | generate highly similar intermediate code.
               | 
               | Also, you'll see these slowdowns even in debug builds
               | that don't ask LLVM to optimize code much.
        
               | dagmx wrote:
               | Pretty rude to start your comment with the assumption
               | that I'm not experienced with Swift. The rest of your
               | comment would be more useful without the unnecessary
               | condescension.
               | 
               | But nothing you said contradicts what I said either. Yes
               | it's easy to get into slow paths with Swift, but it's
               | also easy not to. Granted it takes a lot of up front
               | knowledge to do so.
               | 
               | But even if you just stick to the LLVM portion, llvms
               | debug mode is slower than cranelift and other toolchains
               | debug modes. Debug doesn't mean "no optimizations"
               | whatsoever, nor does it mean efficient paths through the
               | toolchain either.
        
           | jb1991 wrote:
           | What pain points are you referring to? Beyond the lack of
           | meaningful cross-platform abilities, what "real world" issues
           | do you find painful in Swift?
        
             | bsaul wrote:
             | indeed that would be number 1 by a VERY high margin. It's
             | pretty ridiculous to start with "world domination" as an
             | objective and end up 10 years later without a portable
             | stdlib (aka foundation).
             | 
             | Another issue would be a coherent concurrency system. Today
             | we have a mix of gcd and actor system, declarative task,
             | async await, etc which when put together makes me totally
             | unable to understand what's going on in a real world
             | program, unless you're doing like i do in my team : i
             | specifically ban all modern concurrency apis in favor of
             | the old ones.
             | 
             | The same could be said with protocol extension + generics +
             | class + structs.
             | 
             | For each problem, there are approximately 4 possible
             | designs with subtle tradeoffs. Swift team advocates for
             | "expressiveness". My personnal experience is that all
             | patterns and technics will ultimately end up showing in the
             | codebase, depending on the mood of the developer.
             | 
             | In the end, i've started to do like C++ developers end up
             | doing : write guidelines on which language features are
             | allowed, and which are forbidden.
             | 
             | Compare that to go, where there's (at most) one satisfying
             | way to design the problem in the typesystem. As a
             | sideeffect people have to think more about the problem
             | they're trying to solve, and how to simplify it to the
             | maximum.
             | 
             | The end result is that go pushes you toward simple and
             | maintainable code. Swift pushes you toward being fancy for
             | no good reasons.
        
               | KerrAvon wrote:
               | It doesn't sound like you actually understand Swift or
               | the Mac platform you claim it's tied to.
               | 
               | (a) Foundation is portable and available on Windows and
               | Linux.
               | 
               | (b) You are confusing language features and OS features.
               | Async/await is part of the language. GCD is part of the
               | OS.
               | 
               | (c) Banning modern concurrency primitives is not viable
               | forever -- you'll be left behind as the native APIs adopt
               | them.
        
               | slavapestov wrote:
               | > Another issue would be a coherent concurrency system.
               | Today we have a mix of gcd and actor system, declarative
               | task, async await, etc which when put together makes me
               | totally unable to understand what's going on in a real
               | world program, unless you're doing like i do in my team :
               | i specifically ban all modern concurrency apis in favor
               | of the old ones.
               | 
               | There's a layering:
               | 
               | - gcd is the lowest level
               | 
               | - async/await lets you write tasks with suspension points
               | (they wait for events to happen); but an async function
               | is still conceptually executed serially
               | 
               | - the Task API let's you spin up async functions into
               | various arrangements of parallel tasks and wait for those
               | tasks to complete
               | 
               | - 'async let' is sugar for creating a Task to compute a
               | single expression
               | 
               | - for async functions and Tasks to share data there is a
               | Sendable model and various static isolation checks
               | 
               | - actors build on everything else; actors are classes
               | whose state is completely isolated to the actor, and all
               | method calls are posted on the actor's executor
               | 
               | Memory-safe concurrency is hard. There's a lot of ground
               | to cover to replace the kind of things people do with
               | shared state concurrency, and just actors alone are not
               | enough.
               | 
               | > Compare that to go, where there's (at most) one
               | satisfying way to design the problem in the typesystem.
               | As a sideeffect people have to think more about the
               | problem they're trying to solve, and how to simplify it
               | to the maximum.
               | 
               | I like the aesthetics of small languages too, but I think
               | Go picked the wrong small subset. It reminds me of Java
               | in the 1.x days, for x <= 4, where the language had
               | fundamental expressiveness constraints that created a
               | huge amount of unavoidable boilerplate and type unsafety
               | in even the most basic programming situations.
        
               | bsaul wrote:
               | "... reminds me of java"
               | 
               | i was having doubts before go introduced generics. But
               | the fact that they managed to add it so perfectly while
               | maintaining the unambiguous focus on simplicity and
               | structs made me confident they've really nailed it.
               | 
               | The only feature i don't get why they haven't added yet
               | is proper enum to get some kind of ADT. It looks super
               | orthogonal to the language and quite convenient. However
               | at this point i fully trust their taste. If they think
               | it's going to lead to catastrophic design decisions, i
               | fully believe them.
        
               | jb1991 wrote:
               | > protocol extension + generics + class + structs
               | 
               | you are referring to basic languauge features... you
               | consider classes and structs pain points? these are the
               | basic building blocks of the language, if you find them
               | painful this is definitely not the language for you.
        
               | fauigerzigerk wrote:
               | It seems to me that their threshold for introducing new
               | language features is extremely low. If something cannot
               | be made to look flawlessly pretty using existing syntax
               | they will go to any length to fix it, regardless of how
               | much extra complexity they have to introduce.
               | 
               | Result builders are a case in point. Essentially, they
               | didn't like the bracket and the comma between array items
               | in the special case where a function returns only a
               | single array.                 // So rather than this
               | let items = makeUgly {         [           Item("One"),
               | Item("Two"),           Item("Three")         ]       }
               | // It had to look like this       let items = makePretty
               | {         Item("One")         Item("Two")
               | Item("Three")       }
               | 
               | Yes, it's prettier. There's a bit less clutter. But
               | there's a cost too. makePretty uses entirely different
               | language semantics without any syntactical clue at the
               | call site.
               | 
               | So now there are essentially two separate syntax modes in
               | Swift, and every time you look at some code you have to
               | make up your mind on whether to read it in normal mode or
               | in result builder mode. Sometimes that's easy to know in
               | context. But it's another thing you have to pay attention
               | to at all times.
        
               | bsaul wrote:
               | I feel swift really makes it impossible to learn as a
               | language. The number of idioms has grown exponentially at
               | the detriment of orthogonality. I think the red line was
               | crossed with result builders indeed.
               | 
               | Looks like a manager once said "we've got to look like
               | jsx/html, now !" and the poor devs had to obey. It makes
               | absolutely no sense from a language design POV.
        
       | bsaul wrote:
       | i wonder if this isn't going to have the side effect of making
       | some people write more cross platform code in c++.
        
         | pjmlp wrote:
         | The reason why many of us still reach out to C++, is that in
         | many cases the option is only between C or C++, and from both,
         | at least C++ provides some safety knobs.
        
         | fooker wrote:
         | People are going to keep writing libraries in C++ until there's
         | a better option.
        
         | dagmx wrote:
         | I think that's fine as long as there's no performance penalty.
         | 
         | People were doing it anyway. This just eases the friction, and
         | potentially increases performance since many wrappers are
         | really inefficient with regards to data marshalling
        
       | meisel wrote:
       | I've been bitten enough by Objective-C++ compiler bugs (Apple's
       | attempt at mixing Objective-C and C++), as well as bugs in
       | Apple's code in the Swift ecosystem, not to trust the stability
       | here for at least several years. I also don't see how this is
       | much better than just creating a C or ObjC wrapper around a C++
       | library, rather than needing to keep C++'s complicated language
       | features, and Swift's interop with it, in my head as I use the
       | library. Were there people clamoring for this? I can't really see
       | the point.
        
         | pjmlp wrote:
         | History class, Objective-C++ was created by NeXT.
        
         | gumby wrote:
         | You might have better luck using g++ rather than clang for
         | Objective-C++. We originally developed it on gcc (there was no
         | llvm and the NeXT used gcc). By the time Apple switched to llvm
         | I imagine they weren't as interested in Objective-c++
        
           | eschaton wrote:
           | Your imagination is incorrect.
        
           | pjmlp wrote:
           | GCC isn't that compatible with everything post Objective-C
           | 2.0, there is only a kind of partial support.
           | 
           | At WWDC 2023 there were a couple of sessions with
           | Objective-C++ content, e.g. how to extend PyTorch on macOS.
        
         | dagmx wrote:
         | Going from C++ through ObjC++ to ObjC to Swift is pretty
         | onerous. There's a lot of type reduction and conversion along
         | the way and a lot of manual binding generation. Performance and
         | safety footguns are plentiful through that route.
         | 
         | If you have large existing C++ libraries, this (in theory)
         | would really help simplify the process and reduce that mental
         | overhead you mention.
         | 
         | I'm not sure how your suggestion of creating wrappers is better
         | because you'd have to still keep the C++ side for those
         | wrappers and introduce a new intermediary layer to manage as
         | well. Surely having one less layer is desirable?
        
         | KerrAvon wrote:
         | Actually compiler bugs or just badly documented interactions
         | between the two models, leading to misunderstandings?
        
           | meisel wrote:
           | Address sanitizer violations caused when using C++ containers
           | with ObjC objects
        
           | eschaton wrote:
           | This is a lot of what folks refer to as compiler bugs when
           | dealing with ObjC++, yeah, usually when they not asking for
           | help and instead just cobbling together their own
           | workarounds.
        
       | ashvardanian wrote:
       | On a related topic of hybrid Swift and C++ tooling - has anyone
       | used Doxygen/Sphinx to generate HML docs for modern Swift,
       | similar to how people do it for pure C++ projects?
        
         | dagmx wrote:
         | Swift does have docc that does the same
         | 
         | https://swift.org/blog/swift-docc/
         | 
         | I've never had good luck getting documentation working cross
         | language and so I use docc for Swift, doxygen for C++, rustdoc
         | for Rust and Sphinx for Python. Then I just link between them
         | if a project uses more than one language
        
           | ashvardanian wrote:
           | Sure, but how do you style and host those docs? Can you style
           | them identically? We use a combo of Furo + Sphinx + Doxygen
           | for C/C++, Python, JavaScript, Java here: https://unum-
           | cloud.github.io/docs/usearch
           | 
           | For ObjC, Swift, Rust, and other languages we couldn't make
           | it work for now.
        
       ___________________________________________________________________
       (page generated 2023-07-23 23:03 UTC)