Right but you dont have todo this everywhere, just some sporadic use where it makes life a lot easier. It doesn't have to be all or nothing.
F# is probably what you're looking for if you want functional-lite programming with a strong type system, but don't want to deal with the pains caused by static resource management.
If you want to use .NET, F# is a fine choice. But otherwise, and especially in the context of an alternative to Rust, I recommend OCaml.
[0] https://docs.microsoft.com/en-us/dotnet/fsharp/get-started/i...
https://github.com/ionide/Ionide-vim
Meanwhile it has one of the fastest concurrent+GC runtimes, obliterating Ocaml in this regard, and competing handily with JVM or CLR langs.
Finally, it has standard abstractions for concurrency and parallelism that are basically flawless.
Clearly, the hate comes from the association of Haskell with category theory, which is frankly useless/borderline harmful to the working Haskell programmer.
CT was critical to core library devs being able to deliver the main workaday abstractions that make Haskell such an unreasonably productive app languages. But since 2012 you can simply use these main abstractions and enjoy a level of safety and maintainability that rust, c++, ocaml, kotlin, java can't touch.
It's not perfect, but there's been huge improvements of late to tooling (cabal) so there's never been a better time. I really wish the tide could turn, because if you're willing to take on rust for low-level, you're missing out if you don't try haskell for everything else server-side.
You can have the best of both worlds: In many cases, I simply put an object into an Arc, clone that a bunch of times, and pass/store it to wherever it's needed. Then, within loops, I pass a reference to local function calls (instead of cloning the Arc for every call). For any given v: Arc<T>, doing &*v is zero-cost – unlike in many other languages, where you'd have to pass the Arc itself, which would involve atomic increments/decrements without escape analysis.
How it'd be designed and implemented is probably a theme for a separate blog post, not a HN comment.
And then the O in OCaml is all about OOP.
I want to write `toString (1,true)` not `ToStringPair(ToStringInt)(ToStringBool).toString (1,true)`.
Traits, maybe? Switch to an OO model more closely aligned to what the majority of developers understand. Dump all of the line-noise-type syntax.
My Own Toy Language (ComingRealSoonNow)^tm that I started designing had exactly one goal - prevent the majority of memory errors, not prevent ALL memory errors. All I wanted was to indicate when/where an object will be destroyed/mutated. That's enough for me.
Also the basis for one programming language that used to be widespread in the enterprise for quick and dirty solutions, VB and its ecosystem of OCX libraries.
It is more widespread that people think, because when many argue about OOP, they miss the full spectrum of how OOP is approached.
So? Giving up Rust-Traits doesn't mean that I will give up on interfaces as a whole.
I don't like the way C++ does interfaces, for example, but that doesn't mean that my ideal language won't have interfaces.
F# to the rescue. :)