I’ve been programming for decades, though usually for myself, not as a profession. My current go-to language is Python, but I’m thinking of learning either Swift (I’m currently on the Apple ecosystem), or Rust. Which one do you think will be the best in terms of machine learning support in a couple of years and how easy is it to build MacOS/ iOS apps on Rust?

Don’t get me wrong, Swift is OSS and there are things you can do with it apart from front-end dev, but there are usually better options out there for those other things. For example if I want an HTTP server, I’d choose JS, Kotlin, Rust, etc.

For example if I want an HTTP server, I’d choose JS, Kotlin, Rust, etc.

I wouldn’t. Swift is definitely better than any of those choices… and I say that as someone with decades of experience writing HTTP services.

I don’t currently use Swift for any of my HTTP servers - but only because it’s a relatively immature for that task and I’m generally a late adopter (also, I work in an industry where bugs are painfully expensive). But I do use Swift client side, and I definitely intend to switch over to Swift for my server side work at some point in the near future and it’s what I recommend for someone starting out today.

By far - my favourite feature in Swift is the memory manager. It uses an “Automatic Reference Counter” which is essentially old school C or Assembly style memory management… except the compiler writes all of the memory management code for you. This often results in your code using significantly less RAM and better sustained performance than other languages and it’s also just plain easier to work with - as an experienced developer I can look at Swift and know what it’s going to do at a low level with the memory. In modern garbage collected languages, even though I have plenty of experience with those, I don’t really know what it’s doing under the hood and often I’m surprised by how much memory it uses. On server side code, memory is expensive and traffic can burst to levels drastically higher than your typical baseload activity levels, using less memory and using predictable amounts of memory is really really nice.

At one point, years ago, Apple had a compiler flag to use Garbage Collection or Automatic Reference Counting. The Garbage Collector worked just as well as in any other language… but there was no situation, ever, where it worked better than ARC so Apple killed their GC implementation. ARC is awesome and I don’t understand why it’s uniquely an Apple thing. Now that Swift is open source, it’s available everywhere. Yay.

I find compared to every other language I’ve ever used, with Swift I tend to catch mistakes while writing the code instead of while testing the code, because the language has been carefully designed to ensure as many common mistakes are compile time errors or at least warnings which require an extra step (often just a single operator) to tell the compiler that, yes, you did intend to write it like that.

That feature is especially beneficial to an inexperienced developer like OP.

The other thing I love about swift is how flexible it is. For example, compare these two blocks of code - they basically do the same thing and they are both Swift:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create text field
        let textField = UITextField(frame: CGRect(x: 20, y: 100, width: 300, height: 40))
        textField.placeholder = "Enter text"
        textField.borderStyle = .roundedRect
        view.addSubview(textField)

        // Create button
        let button = UIButton(frame: CGRect(x: 20, y: 200, width: 300, height: 50))
        button.setTitle("Tap Me", for: .normal)
        button.backgroundColor = .blue
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        view.addSubview(button)
    }
}
struct ContentView: View {
    @State private var text = ""
    
    var body: some View {
        VStack(spacing: 20) {
            // Text Field
            TextField("Enter text", text: $text)
                .padding()
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
            // Button
            Button("Tap Me") {
                print("Button was tapped!")
            }
            .padding()
            .background(Color.blue)
            .foregroundColor(.white)
            .cornerRadius(8)
        }
        .padding()
    }
}

I’m not a performance expert by any means, but…it seems like the bit about there being “no situation, ever” in which a garbage collector that “worked just as well as in any other language” outperformed reference-counting GC. The things I’ve read about garbage collection generally indicate that a well-tuned garbage collector can be fast but nondeterministic, whereas reference-counting is deterministic but generally not faster on average. If Apple never invested significant resources in its GC, is it possible it just never performed as well as D’s, Java’s, or Go’s?

Check out this interview with Chris Lattner — one of the world’s best compiler engineers and the founder of not only the Swift language but also LLVM which backs many other languages (including Rust). It’s a high level and easily understood discussion (you don’t need to be a language expert) but it also goes into quite a few technical details.

https://atp.fm/205-chris-lattner-interview-transcript#gc

Chris briefly talks about the problems in the Apple GC implementation, but quickly moves onto comparing ARC to the best GC implementations in other languages. The fact is they could have easily fixed the flaws in their GC implementation but there just wasn’t any reason to. ARC is clearly better.

Apple’s GC and ARC implementations were both implemented at about the same time, and when ARC was immature there were situations where GC worked better. But as ARC matured those advantages vanished.

Note: that interview is six years old now - when Swift was a brand new language. They’ve don a ton of work on ARC since then and made it even better than it was, while GC was already mature and about as good as it’s ever going to et at the time. The reality is garbage collection just doesn’t work well for a lot of situations, which is why low level languages (like Rust) don’t have a “proper” garbage collector. Arc doesn’t have those limitations. The worst possible scenario is every now and then you need to give the compiler a hints to tell it to do something other than the default - but even that is rare.

Thanks for sharing the interview with Lattner; that was quite interesting.

I agree with everything he said. However, I think you’re either misinterpreting or glossing over the actual performance question. Lattner said:

The performance side of things I think is still up in the air because ARC certainly does introduce overhead. Some of that’s unavoidable, at least without lots of annotations in your code, but also I think that ARC is not done yet. A ton of energy’s been poured into research for garbage collection… That work really hasn’t been done for ARC yet, so really, I think there’s still a a big future ahead.

That’s optimistic, but certainly not the same as saying there are no scenarios in which GC has performance wins.

Create a post

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person’s post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you’re posting long videos try to add in some form of tldr for those who don’t want to watch videos

Wormhole

Follow the wormhole through a path of communities !webdev@programming.dev



  • 1 user online
  • 1 user / day
  • 1 user / week
  • 1 user / month
  • 1 user / 6 months
  • 1 subscriber
  • 1.21K Posts
  • 17.8K Comments
  • Modlog