Rust isn't only great because it's low level. Things like sum types (called enums in rust), pattern matching and expression orientation mean that it is often much more expressive than other languages for high level code.
That, and that it has better support for imperative features than most ML languages. You can combine your fancy combinators with mutable variables and for-loops when just want to get something done quickly.
In general, Rust just has all the little details right. It's hard to describe that in concrete terms, but it makes using it a very smooth and satisfying process. I get a similar feeling when using postgres: there's usually a nice way of doing what I want, and I rarely come up against unwelcome surprises.
ML has always had easy mutables in the form of references, and the closest deployed language to Standard ML (Ocaml and Reason), has always had for-loops and while-loops. Mutable references are used frequently.
Rust is great because it's low level, high-performance, non-garbage collected and it's primary inspiration for higher-level programming is languages like ML and Haskell.
Thanks! I actually do use Rust as my main professional language (since my company’s product is based on timely-dataflow and differential-dataflow, so it was the only natural choice).
But I’m always curious about how it stacks up against other languages I’m less familiar with that share similar ideas.
Right. You could use F#, and get the pretty big .NET ecosystem with it. I think some people are mainly attracted to Rust due it's novel and open-source attributes. There is certainly a hype factor involved in it. In my opinion Rust is great (I use it), but I think it's main strength are in different domains than web applications.
One of my favorite features of Rust as someone who dabbles is that thread safety is expressed in the type system. F# is perfectly happy to let me share mutable data across threads without any synchronization, while the Rust compiler knows whether something can be safely accessed because you've either transferred ownership, or the type is thread safe.
The ownership system is also a very clever approach to managing mutable state. Usually in F# you'd get something of the same effect by using immutable structures and creating new copies, which does have a small performance impact
IMO both language types offer shared state and immutable data structures so I don't see them as mutually exclusive. As the Rust guys I've heard say "sharing state and mutation are fine, just not together". It's a question of whether the problem your trying to solve is better as a highly mutable one with "sharing" (e.g I'm thinking system programming with contended system resources) or you want to share data across many threads simultaneously and are happy with slower single threaded performance for greater multi threaded throughput (writes are rare so sharing and locking on an atomic ref on occasion is OK so you want structural sharing of data). Rust helps the coder avoid the issues when coding in the traditional "sharing and mutation" paradigm especially without a GC; languages like F# have some modern things to do this like atomic refs for data sharing, flagging mutables, async lock types, support for imperative programming etc. Both approaches work and IMO suit different kinds of problems; good to have both available.
I call Rust a hybrid of Haskell and C++, it has most of the powerful type features you come to rely on with the MLs but the additional low level control and default imperative behavior of C/C++.
I came from Haskell to Rust and it really is a joy to program in.