I started writing these responses in a Slack channel of developers I participate in as I worked through the Swift book. I realized after a bit that it would make a better blog post than chat room content, so here we are. This is all entirely off-the-cuff: me just thinking out loud as I read; this is by no means expert opinion.

I later turned this into the first part of a whole series comparing Rust and Swift!

..< – seriously? That has to be one of the most annoying operators I’ve ever seen. It ends up with cognitive noise because <name initially processes as “starting a generic” and you have to re-parse it visually and mentally.

After the first chapter of the Swift book, my impression is “a poor man’s Rust”; my gut feel based on that first pass and everything I’ve seen and read about Swift over the past two years is that it’s roughly what you would get if you took Rust’s syntax and replaced Rust’s hard safety goals with the aim of mapping to ObjC semantics. (To be fair to Apple, that interoperability was probably necessary.)

An example that jumps out at me as immediately illustrative of the difference in approach the languages take is the way you pass structures by reference vs. copy. In Swift, that’s done via two completely distinct language constructs, struct s and class es respectively. In Rust, there is just the struct type to handle both of those. They’re immutable unless you declare them with mut , and you can pass them via copy simply by implementing the Copy trait (which seems roughly analogous to Swift’s protocol , but I’ve not yet dug deeply enough to see how they differ). Those things aren’t baked into the language, but use simpler language building blocks to define behavior into the library.

I saw someone do a write up a while back arguing that Go isn’t a bad language, it just isn’t a good language. My first impression of Swift, after having spent the last month with Rust, is very much along those lines.

Huh. Here’s something that I appreciate about Rust, Haskell, and others now that I didn’t before: there’s a difference between implicitly/automatically importing a prelude or a given set of standard library functions, and having actually global functions. Does Swift actually have functions like print in a global namespace, as the book seems to imply, or they being imported automatically a la Rust/Haskell/etc.? Edit: it appears Swift does likewise, but that you can’t access the relevant module directly. Which is halfway there.

Hmm. Why have Double and Float —just for ObjC interop, I guess? Edit: follow-up from a conversation with a friend: it’s because you have 32- and 64-bit architectures out there; sometimes you don’t want 64 bits of floating point precision for that reason. Note that Rust also has this distinction; you can declare things as f32 or f64 .

Extending the above note on class es and struct s and protocol s vs. Rust’s approach: the same thing is true about extension , which is a distinct concept from implementing a protocol ; again, in Rust these are both just handled with a single language construct, impl . That’s not because impl is overloaded, but rather because the underlying language machinery is the same for the two things. (edited)

(I’ve a feeling learning Swift is going to turn me into even more of a Rust fanboy.)

Reading the two books in close sequence like this is proving really productive mentally for thinking about how the two handle the same issues. I’ve never done anything quite like this before, and it’s fascinating.

I have an increased appreciation for Rust’s use of semi-colons to turn expressions into statements, and thereby to distinguish clearly between the two (among other things, allowing for implicit return of anything that’s an expression).