> has an edge on some domains due to having unboxed types
If a language makes "unboxed types" a feature, a specific distinction, and has to sell "removing global lock" as something that is a massive breakthrough and not table stakes from 1.0, it can't possibly be compared to F# in favourable light.
I vouched for your dead comment because I get where you're coming from. But OCaml 1.0 was in 1996 in an academic setting. I care about the language I can use now, not the one I didn't use.
Let's not dismiss that their solution to remove the global lock has been both simpler than Python's (better funded?) ongoing work and backwards compatible; and the multicore support came with both a memory model with strong guarantees around data races, and effect handlers which generalize lightweight threads.
I agree that lack of unboxed types is a fatal flaw for several domains (Worse, domains I care about! I usually consider Rust/Go/.NET for those.) But when the comparison with OCaml is favourable to F#, the gap isn't much wider than just unboxed types. F# has an identity crisis between the ML parts and the CLR parts, its C# interop is decaying as the ecosystem evolves, and newer .NET APIs aren't even compatible with F# idioms (here's a .NET 6+ example [1]).
Ref structs are hard to solve because they require, in some ways, a lot more work than the way C# solved the lifetimes as the lifetimes in F# may need to become much closer to what they are in Rust. Some constructs may not be able to consume them still (can’t move ref struct into an object with effective lifetime ‘static) and there really is no easy solution short of language editions and breaking standard library changes. A limited improvement is possible, but we’re still in the realm where the lifetimes may become a part of type identity or somehow generalized over, which is hard.
OCaml predates multicore CPUs. Having a global lock was basically free at the time it was invented. It's totally crazy to dislike a language because the authors made a decision that was obviously correct at the time.
F# uses the CLR term "value types" instead, or sometimes "struct" types as in the C# keyword.
These are usually defined with the [<Struct>] attribute over a regular type definition, or using the struct keyword before tuple/anonymous record types. Also, the original 'T option type now has a value-type successor 'T voption.
If a language makes "unboxed types" a feature, a specific distinction, and has to sell "removing global lock" as something that is a massive breakthrough and not table stakes from 1.0, it can't possibly be compared to F# in favourable light.