This looks like a great resource! https://rust-exercises.com/03_ticket_v1/07_setters
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.
There’s a world outside of web development.
He's right, though. Languages today shouldn't force you to jump through low-level hoops if you just want to write high-level logic. Likewise, the low-level devices should be easily and ergonomically accessible. Rust is phenomenal at the latter but weak at the former.
What languages scale better in that regard? Genuinely interested in recommendations.
C# and C++. In C#, you can use pointers but most people don't even know because they so gracefully become invisible. Also ref/in/out keywords are there when you need them and invisible when you don't. Likewise, you don't even need to know about move semantics in C++ to make a simple web server.
That said, C# and C++ most certainly have their fair share of issues.
Compared to most popular high level languages like Java or Go, Rust is seriously at the more expressive end (read: can be higher level).
But who's forcing you? Oh .. the companies jumping on the latest "in Rust" hype. I see.
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.
Also, just because these examples are verbose doesn't mean that all Rust code is this way. Accessors/mutators aren't used super often in my experience, and the builder pattern is used occasionally, but isn't pervasive.
(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 ;)
Agreed. There's also another aspect at play: to build knowledge one step at a time with this learn-by-doing approach, you have to get learners to write code that's not perfectly idiomatic along the way. You then correct and refine those first drafts as you progress along.
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.
interesting!
You get ridiculous performance gains with Rust a web backend. Even Microsoft is rewriting part of their C# backend to Rust on the 365 application side of things. Which is where you get to deal with the hefty ms-graph api which handles literal fucktons of data.
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.
Office team never was a big .NET fan, and they were partially responsible for Longhorn's failure, see also Hilo C++ tutorial made by the team as part of Vista SDK tutorials, or their love for Webwidgets to C++ code, so that isn't that surprising.
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.
But like the Office services, these are all significantly older than Rust. Bing the branding is like 15 years old, the underlying service is older still (as "Live Search")
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.
And the strategic priority of those business units has been to take advantage of all the performance improvements that have come out of Midori toolchain into Core CLR/Native AOT toolchains, while exposing MSIL features only available to C++/CLI to C# as well.
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.
Given your interest in C++/CLI, I wanted to give some clarification in regards to its relationship with .NET platform as a whole.
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...
Thanks for the deep dive.
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.
Bing had been heavily using .NET Framework and has migrated to .NET Core/.NET since then with great results: https://devblogs.microsoft.com/search?query=Bing&blog=%2Fdot...
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.
Well, nobody forces you to use the setters/getters pattern. For internal implementation, you could access everything directly. For example, Zig encourages this style of programming.
In my experience in Rust, the use of getters and setters is less common compared to some other languages like Java.
`into()` just converts something from one type to another, like an integer to a floating point number. Would you have liked for such conversions to happen implicitly? Because let me tell you, that is one of the most painful features of C++, and modern well-written C++ typically disables implicit conversions in one way or another.
(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.)
It seems like Rust is doing a pretty good job of applying to web apps and APIs:
https://www.techempower.com/benchmarks