4 ms·
Interesting. Asking as someone who's never programmed with Swift or Rust, but is familiar with the syntax/ideas of each, I'm curious why you say that?
by rattray 4y ago
Interesting. Asking as someone who's never programmed with Swift or Rust, but is familiar with the syntax/ideas of each, I'm curious why you say that?
- dcow 4y agoIf you don't care about performance and "zero cost abstractions" and are more interested in Rust for its memory safety, then most of your Rust programs end up with a lot of syntactic and library bloat to add those "costly" (but convenient) abstractions back in, like explicitly cloning or wrapping types in Rc and Arc or just always taking ownership of borrowed data by constructing owned types with it. And then there are lifetimes which can be and are elided in almost all uses cases so they're ultimately just confusing whenever you actually have to deal with them. C.f. Swift, where the default is in my experience what "higher level" rust programs end up looking like, but with much nicer and cleaner syntax. And Swift has a very nice rather memory safe API for calling into C or otherwise just generally accessing scoped pointers when needed. This same api can actually be used to expose more performant apis to underlying data etc. when needed. It's kinda the reverse of Rust. It feels like Rust is two languages in one: a high performance zero cost abstraction language that tracks pointer ownership, and a package rich and hyper explicit application language build atop all the guts. That's why I say high-level application use cases, because most high-level applications are not concerned with raw performance but rather with functionality and user experience. The parts that are concerned with throughput can be implemented using tooling where those knobs are available. I have enjoyed writing a cli and api server and various libraries in Rust. But every so often I am left wondering when Swift might be able to replace it for my higher level concerns. Alternatively, it would be neat to see some effort put behind a "convenient rust" type of compile mode for modules where you could compile with things like implied clones, unified owned vs reference types, auto-arc/box, etc.
- rattray 4y agoMakes sense, thank you for explaining! Personally I'd love to see a forked flavor of TypeScript with static compilation and multithreading (which implies a lot more immutability, etc). Maybe I should give Swift a try…
- yyyk 4y ago>If you don't care about performance and "zero cost abstractions" and are more interested in Rust for its memory safety... Just about GC language has similar tradeoffs. The question here would be why Swift over Go/C#/Java/Python/Typescript?
- rattray 4y agoWell that's easy. Swift is: 1. Much more expressive and featureful than Go 2. More concise and modern than C# (debatable maybe?) 3. Less JVM than Kotlin (the apples-to-apples; Java is a much worse language) 4. Way, way faster and more typesafe than Python 5. Better support for parallel execution (and probably fine-tuning other performance knobs) than TypeScript
- yyyk 4y ago1. Definitely, but Go is well very optimized for concurrent network apps. 2. I think the C# team has done very well modernizing. The runtime is a bit of a bother though. 3. There's Kotlin/Native and Kotlin/JS. 4. Python has dev speed and ML benefits. 5. If you're going this way, performance probably isn't your main goal? All-in-all, Swift is interesting, but (IMHO) lackluster crossplatform support and toolchain is a problem.
- dcow 4y agoI have used all those languages seriously save C# (only lightly) and can safely say Swift knocks them all out of the park in terms of actually writing applications. Indeed, its cross platform support is lackluster, thats why we’re here.
- zozbot234 4y ago> Alternatively, it would be neat to see some effort put behind a "convenient rust" type of compile mode for modules where you could compile with things like implied clones, unified owned vs reference types, auto-arc/box, etc. If you can come up with a precise transform from "convenient/sloppy rust" to the underlying language, it can already be implemented via proc macros and the #[attributes] syntax. This is how async programming was prototyped in Rust before it became part of the language proper. Though I'm not sure it's fair to describe Rc, Arc, Cow etc. as "library bloat". It certainly adds some boilerplate, but it's designed to stay manageable. (Arguably, good coding practice should also informally document why the Rc, etc. is needed and can't be refactored away, i.e. what parts of the program are controlling the lifetime of each Rc'd object.)
- dcow 4y agoMaybe bloat wasn't the right term (was thinking that it bloats the code, not the resulting program), but when you're in a scenario where you're doing one thing more often than the default, it feels like boilerplate to have to continually say `String::from("some string ref")` (as an example) just to take ownership when that's what you want every single time. Or, at least something like an "owning assignment" or "owning deref" operator that automatically adds the `to_owned()` call would help reduce boilerplate. Maybe it was a mistake to conflate lifetimes and generics. It wouldn't be so bad to deal with references in Rust if you didn't have to include lifetime parameters when building APIs. It seems silly that (in my experience) people gravitate toward structs with owned fields just to avoid specifying the lifetime of a borrowed field.