69 comments

[ 3.8 ms ] story [ 58.0 ms ] thread
Glad to see "Swift is good now" taking the place of "year of the Linux desktop" in a post-Steam Deck world.
>Swift is more convenient Rust

Nah.

There’s definitely areas where I agree Swift is more ergonomic.

Parameter defaults, and null short circuiting are two of them.

I find writing Swift is faster for me, and it’s easier to learn for people than Rust. Also Swift interop with other languages is much simpler.

Though there are way fewer resources to learn Swift, and cargo is superior to SPM. And of course rust is better cross platform today, but Swift is closing the gap.

I think they feel like very similar languages overall, and they both influence each other.

Even if it's the same (faster horse?) I would rather use Rust for the fact it's development is not tied to a big tech company which could abandon it if they liked. Yes it could continue on as a fork but it's development velocity would suffer.
Interesting. I'm not totally sold - still seems like Swift is quite niche and Apple-specific - but I might take another look.

Also you might want to rework the `Box` example because you don't actually need to use `Box` in that case - the `Vec` already provides indirection.

I was surprised how similar their approach was to memory management. The creator is doing the same thing for Python as they did for Objective-C, making way for a new wave of Swift and Mojo, although we'll have to see if the latter grows to the same success.
> Consider an enum that represents a tree. Since, it is a recursive type, Rust will force you to use something like Box<> for referencing a type within itself. > > enum TreeNode<T> { > Leaf(T), > Branch(Vec<Box<TreeNode<T>>>), > } > > (You could also us Box<Vec<TreeNode<T>>> instead)

This is wrong, you don't need a `Box` here. The Rust compiler forces you to have a layer of indirection, but `Vec` already does that.

Broadly agree but, as is most things, the devil is in the details!

- Xcode. A really rough ide that has a hard time at scale, choking on package refreshes, many targets, and more. It has a special entitlement so you can't even binary patch it if you want to fix it!

- Build systems. Cargo is _much_ easier to work with than SPM.

- Macros support, codegen is still largely done outside of the macro system, which should indicate its use.

- Linter / format support. Yeah, it exists, last I checked it's just a good bit worse.

- Performance. There are MANY performance cliffs in Swift; most can be fixed by a sufficiently determined compiler developer, but at this point we've kinda departed talking about the language as-is.

- Type inference time. Swift's bidirectional type inference causes a ton of choking on complex expressions, which is a real problem with its number one use case, SwiftUI.

- An exacerbating factor on the above, imports are all implicitly module-scoped, meaning that changing a single file means recomputing the types for all files in the module. And because SPM and Xcode have such a rough time with multiple targets, that usually means that a single change can lead to recompiling all Swift files.

- Weirdness around classes and structs? I understand that they had to do it for objc compatibility, but I would've found it much cleaner if they'd just from the start had something replacing class, like a fully-sugared `final class Box<T>` that replaces all uses of class.

I agree that for the most part it _could_ be an easier rust, but between including bidirectional type inference without a cut operator and poor tooling I struggle to find where it's actually easier in cases that you can't just use typescript and dodge all the non-typecheck compilation headaches entirely.

> Swift is better for writing UI and servers and some parts of compilers and operating systems.

For UI, why would anyone choose a language that has no automatic GC that can handle cycles?

I generally like Swift, but async is a mess, it feels like they come up with a new async library every release
I don't really see the advantage of switch statements over match statements.
Writing Swift is really fun! Last year I built a game and a macOS app (now working on another app) to get some proper hands on experience and I was very impressed. Wrote about it here[1].

I'd love for the experience outside of Xcode to get better (even on a mac, developing for macOS/iOS) but I have to say that I didn't find Xcode to be _that_ aweful. I've certainly used worse IDEs, which is partly why I dislike IDEs altogether.

1: https://log.beshr.com/notes-on-swift-from-building-an-ios-ga...

If you want more convenience from Rust and do not want to mess with Rust borrow checker, you do not really have to switch to Swift: you can rely on Rust reference counting. Use 1.) Rust reference-counted smart pointers[1] for shareable immutable references, and 2.) Rust internal mutability[2] for non-shareable mutable references checked at runtime instead of compile time. Effectively, you will be writing kind of verbose Golang, but keep Rust expressiveness.

[1] https://doc.rust-lang.org/book/ch15-04-rc.html

[2] https://doc.rust-lang.org/book/ch15-05-interior-mutability.h...

> There is a perception that Swift is only a good language for Apple platforms. While this was once true, this is no longer the case and Swift is becoming increasingly a good cross-platform language.

How good is the developer experience on a non-Apple platform really? Linux is my primary platform and my perception is, that allmost all of the swift eco system is for Apple. Libraries, tools, documentation, IDEs, tutorials, etc. all assume, that you use an Apple.

Can someone tell me who does not use an Apple-device and uses swift?

Until you get to the Swift concurrency stuff, or you try to use Swift on a backend or non-Apple system - then it’s hot garbage.

If Rust is too low level for you, you can write Go or Kotlin or even something new and fresh like Gleam.

This article made me actually interested in learning Swift. Anyone recommend a good place to start?
Riiiiight. No. I'm a Mac user for decades, former Obj-C hacker, have tried and tried again and again to use Swift (and I have quite a few CLI apps written in it), but the thing has been a clusterfuck of paper cuts and very minor but significant changes over the years, and I gave up waiting for it to settle.

And it's not a more convenient Rust. I'd rather use Zig or Go (neither of which are worthy in the eyes of true Crustaceans, but which just get the job done).

No thanks, too tied to Apple and closed source development models.
I really don't understand what's the point of such comparisons. Swift uses subtyping, while Rust uses typeclasses. Even looking only at their type systems, the two are completely different. You can't assume they are similar just because they both use the Latin alphabet.
I would tend to disagree; fundamental to Rust is the concept of zero-cost abstraction. Swift does not do that.

I my view, and I might be wrong, many features of Rust are chosen specifically to have the language comply to the zero-cost rule. Such as the ownership model.

Toady I used GLM 4.7 to port a C++ project of mine to Rust, so I could read and toy with it, to get into the language: https://codeberg.org/RickStanley/agatetepe-rs.

Really interesting results, not sure how well it is written but works. I was quite found of Rust syntax; it certainly is not as convoluted as C++ (in my opinion).

Then I read this article. Since I was already eye-balling Swift for some time, I decided to give it a try and port to it, using Rust implementation as reference, and this time, without much of A. I. assistance, if I could help it.

I'm using an qcow2 Debian trixie arm image in UTM as playground. I found out that there is no packaging for Debian at the time of this writing: https://github.com/swiftlang/swift/issues/60690. No problem! They have a script for installing: https://www.swift.org/install/linux/

    curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \
    tar zxf swiftly-$(uname -m).tar.gz && \
    ./swiftly init --quiet-shell-followup && \
    . "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \
    hash -r
But, god damn, the size is huge,

    Unsupported Linux platform
    Debian GNU/Linux 13 (trixie) is not an officially supported platform, but the toolchains for another platform may still work on it.
    Please select the platform to use for toolchain downloads:
    
    0) Cancel
    1) Ubuntu 24.04
    2) Ubuntu 22.04
    3) Ubuntu 20.04
    4) Ubuntu 18.04
    5) Fedora Linux 39
    6) RHEL 9
    7) Amazon Linux 2
    8) Debian GNU/Linux 12
    Pick one of the available selections [0-8] : 
    
    8 
    Installing swiftly in /home/debby/.local/share/swiftly/bin/swiftly...
    Creating shell environment file for the user...
    Updating profile...
    Fetching the latest stable Swift release...
    Installing Swift 6.2.3
                      Downloading Swift 6.2.3
    100% [========================================================]
    Downloaded 947.6 MiB of 947.6 MiB
    
    Verifying toolchain signature...
    Extracting toolchain...
    The file `/home/debby/ent/agateteper/.swift-version` has been set to `Swift 6.2.3`
    The global default toolchain has been set to `Swift 6.2.3`
    Swift 6.2.3 is installed successfully!
    There are some dependencies that should be installed before using this toolchain.
    You can run the following script as the system administrator (e.g. root) to prepare
    your system:
    
        apt-get -y install libicu-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev 
        libncurses-dev libpython3-dev libxml2-dev pkg-config uuid-dev libstdc++-12-dev

947.6 MiB ! I wonder why is that...
Swift is a neat language, but it’s a hard sell for server-side software. The ecosystem is tiny, and there’s nothing you gain from using it instead of Go or Rust for infra / distsys.

Also, it works okay at best with VS Code, and you couldn’t pay me to use Xcode.

Kotlin tried doing similar things to gain adoption on the server side. But server-side programming is a crowded space, and people just don’t like writing distsys code in another JVM language. Swift’s story is a little better on that front.

If you want a quick-and-dirty language, Python and TypeScript do the job. For perf-sensitive, highly concurrent environments, Go is hard to compete against. A lot of ops tooling and infra code is written in Go. For systems programming and embedded code, Rust is a better choice.

So while it’s fun to think about what language X gives you in terms of syntax, in practice it’s rarely enough to pick a language like Swift for your next non-toy backend distsys work.

Also, Apple. Given their stance against free and open source software, I wouldn't be too thrilled to pick a language that works better in their walled garden.

The target group for server-side software are iOS and macOS developers that also need a server component, thus like the JS folks, they get to use the same programming lanugage.
> Rust invented the concept of ownership as a solution memory management issues without resorting to something slower like Garbage Collection or Reference Counting.

This is plain wrong, and it undermines the credibility of the author and the rest of the piece. Rust did not invent ownership in the abstract; it relies on plain RAII, a model that predates Rust by decades and was popularized by C++. What Rust adds is a compile-time borrow checker that enforces ownership and lifetime rules statically, not a fundamentally new memory-management paradigm.