(I have historically been very skeptical of Rust on the web, but by now, I find it pretty pleasant. I of course know Rust very well already though.)
Understatement of the week ;)
In the case of setters, we get rid of them at the end of that chapter by using the newtype pattern thus guaranteeing that field invariants can't be broken even if you can access them directly.
Just do your thing and be good at it.
PS: There was this VSCode extension to do BI stuff in the IDE (quarylabs/quary) showed here on HN and once I saw the CLI core having "Rust-based" as a feature I just closed the tab. What does "Rust-based" even mean? The tool may have been good but Rust is not a feature.
That said, C# and C++ most certainly have their fair share of issues.
Anyway. It is more verbose than something like Go or Python. I’m not sure it’s really so bad compared to most languages, but some of the benefits you get from the verbosity is that you gain a lot of control over how you use mutability and the borrow checker or how you work with memory in general. Things which are foreign to many developers today, but you shouldn’t compare a Rust implementation to a C#/Java/Python/Ruby/Node/Go api, you should compare it to a c/c++ api… which is where Rust is just so much “safer” for production.
We have Node APIs in Typescript, we have Python APIs with FastAPI, we have C# web APIs and we have a few Go APIs. We’re perfectly happy with those, well maybe not the fact that we use so many languages, but we’re happy with them. Where we use Rust is where we used to use C, and the benefits are massive. You get the same sort of performance, but you also get an environment where programmers with less experience working without garbage collection can do work we just couldn’t have them do with C.
Quite debatable. My experience is different. I have ported some tiny amount of Go code to async Rust and it turned out to be simpler and shorter. Way less boilerplate related to cleaning up the resources - in Rust it was actually zero additional code thanks to RAII and really nice channel design, while Golang needed a lot of additional stuff like waitgroups or manual defers plus more channels to communicate obvious things which in Rust are simply passed by result of a future.
Rust also feels a lot more expressive than Go with functional collection transformation chains (map, reduce, filter, grouping etc) where in Go this is loops and ifs all the way down. Rust is very close to Python in this regard.
It isn't as if C# vlatest wouldn't be able to take up the task, Bing, XBox game servers, and other large scale services are fully on .NET.
So when this stuff was built the high performance option was C++ and there is an obvious reason to avoid that if you can. Rust means you can have the excellent performance without the absurd foot guns. Whether you chase that depends on other strategic priorities.
Just like Rust can take advantage of the LLVM IR features used by clang, so does C# in regards to the MSIL used by C++/CLI.
Indeed, there have been historical influences from Midori, C++/CLI, CoreRT[0], .NET Native/UWP and work done that got merged into earlier releases of .NET Core (up until 3.1), in particular, Span<T> and compiler optimizations.
However, pretty much all work done since Core 3.1 is independent, rather than "migrating of features from". The last and only exception would be NativeAOT which still uses project RedHawk name in some places in the code that haven't been renamed, referring to Midori and .NET Native (because NativeAOT has started with a big chunk of the codebase from the latter). But NativeAOT aside, pretty much all .NET features are exposed through IL and surrounding metadata, making it possible for any language to target these (rather than being related to C++/CLI), even if initially designed with C# in mind.
As far as I'm aware, C++/CLI itself uses MSVC to compile C++ code and then just generates bindings and glue code with other .NET assemblies, embedding itself into final .NET assembly produced that would use it. It did not target CIL with C++, like that new project for targeting CLR with Rust does, but rather CTS which is a quite old concept at this point. It is also limited to Windows only[1].
So the more accurate comparison would be between projects that produce .NET assemblies containing IL and projects that produce LLVM bitcode files containing LLVM-IR.
[0] https://devblogs.microsoft.com/dotnet/performance-improvemen... search for CoreRT and this is pretty much the only reference you can find in terms of work migrated from earlier projects
[1] https://learn.microsoft.com/en-us/dotnet/core/porting/cpp-cl...
As a user I know C++/CLI, since it was initially released as Managed C++ in .NET 1, replaced by C++/CLI in .NET 2.0.
They have two ways of compiling code, fully managed, meaning pure MSIL, where the Assemblies are considered as safe as other .NET languages by the PE Verifier. In this way, some UB behaviours and not so sane stuff from C day's, is forbidden in C++/CLI and will trigger a compilation error.
Mixing in native code. In this way everything from C++ is allowed, the resulting Assembly will be a mix of MSIL and native code generated by the Visual C++ backend, and will fail verification as a safe Assembly, being only allowed in unsafe code contexts.
My reference to it, is because until the improvements started in C# 7, the only way to make use of specific CLR low level capabilities, was to either do Reflection.Emit(), or reach out to managed C++/CLI.
You are fully aware of this, but many keep forgetting MSIL was designed for C like languages as well, and just like the hyped WebAssembly has all the necessary features to take full advantage of it.
(Note: For the specific example of integer-to-float, Rust has an alternative built-in syntax, but `.into()` is the canonical way that also works in generic code.)
In my experience in Rust, the use of getters and setters is less common compared to some other languages like Java.
This shows why I wouldn't use Rust for anything. Seems like a lot of verbosity for gains that don't really apply whatsoever for the kind of work I do (web apps and APIs). You have to remember let/mut fine, but then ownership/borrowing, and finally this `into()` thing - yuck! Like washing your face with sandpaper.