NOTE: I considered asking this in a proper subreddit, but I don't have enough karma.
Is there a strongly-typed language syntatically like Rust that is already garbage-collected by nature (e.g. mark-n-sweep)? I never did multithreading, but it's also interesting if all types were something like Send + Sync.
NOTE: There are crates like gc for Rust that provide a Gc capsule, but I wanted to avoid things like #[derive(Trace)]. I want something more natural.
I was thinking of something similiar to the inexistent ECMAScript 4 language (were types exist at runtime), but using the Rust syntax.
About TypeScript, if it really were neccessary, I guess a dialect could work to target more efficient bytecode in some form, but there's only one project for that at the moment:
It's not exactly an issue with GC. I was trying to have mutable fields within a multithread type (under Arc) and got in trouble because there was no multi-thread version of RefCell, so I was forced to wrap each field into yet another Arc: Is there a multi-thread version of std::cell::RefCell? Not a trouble at all, but that could be memory-inefficient.
I knew of Scala, but I didn't want to try it because ScalaDoc doesn't support Markdown. It supports something similiar to Markdown, but very unfamiliar.
If you really just care about syntax (which seems odd, since if there's anything people think Rust is mediocre at it's usually the syntax), then there's probably some JVM or DotNet language that's pretty close. C# has curly braces and structs and such, say.
But note that a bunch of Rust's core value propositions mix poorly with GC. GC is all about not having a deterministic time at which things are released. Which is why they regularly tell you to not use finalizers. If I stick a LockGuard into anything GC'd, now I can't just rely on the Drop to release it, because who knows when that'd run. And if I have enough lifetime tracking to know when something is done without the GC, then I don't need the GC in the first place, because I can free the memory when I know it's done -- the same way as I release the lock or close the file. (The memory is the easy part, in a way.)
I'm still not sure what issue you were having with Mutex that you felt you needed Arc twice (I'm probably just misunderstanding what you're saying), but keep in mind that if you need it explicitly in Rust, it's probably implicitly done by other languages, or you need to do it but you don't get any warnings.
For example, a C# List is essentially an Arc<Mutex<Vec<T>>> (it's internally an object on the heap with a T array of storage on the heap and a length, and every object also is a Mutex), but if you are sharing it across threads you need to remember to lock it without any warning.