Rust with a GC (and therefore without borrow checking). I'll copy the stuff I wrote on a twitter thread recently below:
Rust's borrow checker is the most innovative but also most inconvenient bit, and GCs are certainly more convenient.
But Rust is much more than that:
- Rust traits are like typeclasses, but you can still use dot notation for better discoverability, which IMO makes them even beter (no, hoogle is no substitute for automatic, instant inline editor documentation).
- Macros in Rust are very powerful: not only can you control what they generate, but you can also control error messages via `compile_error!` and the exciting upcoming compiler diagnostic API. This means great DX is possible, even when macros are used!
- Rust lets you write code that uses Result that is almost as compact as exceptions in other languages. The `?` (previously try! macro) operator implicitly early-returns if there is an error. With a bit of effort, its usable even in functions such as `map` and `flat_map` via `collect`
- Traits are really helpful here in two ways: You can implement `From` for standard error types to ensure they're converted to your error type (Or you can use an awesome ready-made crate that lets you add context such as https://docs.rs/anyhow/latest/anyhow/). Traits also help .collect() work with Result regardless of whether the iterable is an iterator, vector or some other data structure.
- rust-analyzer and how well it works in vscode.
- Cargo, the Rust package manager, just works. No fuss. If you want to setup a monorepo of multiple crates, binaries, libraries, no problem - it can do that too and it will know how to handle it. Contrast with JS/TypeScript ecosystem, where monorepo setup is the topic of blogposts.
- Rust documentation culture is crazy good. Crates go as far to add a copy-pastable example to many of the functions. Thanks to python style doctests, those examples are also automatically tested. Almost all crates have an excellent "README" page that introduces the library properly. Contrast with Haskell where there's none of that.
- Some things available are just plain cool. For example, just add the Rayon crate https://docs.rs/rayon/1.5.3/rayon/ to your project and replace a few key `iter()`s with `par_iter()` and you have a multi-core program that is 4-8 times faster on your average machine.
- One of my favorite macro packages is peg (https://docs.rs/peg/latest/peg/) - it uses the compiler_error api to tell you if you've written a left-recursive definition (not good for PEG). Its super easy to use and as is Rust tradition, produces excellent parse errors with locations.
- All those C library bindings available. Enough said.
- Its really cool and convenient that you can produce a single binary. Thanks to rust-embed (https://crates.io/crates/rust-embed) its also really easy to keep it a single binary in many situations.
- Last but not least, the community goes above and beyond to make people feel welcome.