Finally somebody understands this.
Finally somebody understands this.
Rust is not difficult because of lifetimes, it just gets in the way of freely prototyping what you want.
This situation is slowly improving with the compiler getting better and better.
Then there is some annoying macro usage. Some Rust code looks truly alien.
I'm not a rust programmer, but I guess that's an issue if you come from a dynamic language, not from c++.
With Go and Rust I have to make a dedicated function somewhere and then have it be called after starting the program. Ain't exactly rocket science but the difference in time to do it and the convenience is still very stark.
I love working with Rust for the stability and speed it gives me but the value proposition and daily coding flow are VERY different compared to a dynamic language. With Elixir I am mostly just brain-dumping and stuff happens extremely quickly and fluidly, with Rust I kind of sigh and accept that the next 10 minutes I'll just be writing and writing. Might even zone out and make a dumb mistake because I have to spend more keystrokes and more time to do something I'll do in a minute in Elixir.
Maybe it's time to look for snippets support in my editor. Or start asking ChatGPT for them.
I don’t think being able to brain dump code is a good thing and it leads to an unmanageable mess when you have a large codebase. Types are essential as far as I’m concerned, but I constantly have to get into arguments with the dynamic type fans because their “flow” Is being restricted.
Brain-dumping is simply a way to iterate and figure out what works and what doesn't, quickly. After I do it I take the requisite time to emulate exhaustive pattern matching, and add tests that cover the functionality well.
My problem with Rust, and I love the language a lot, is exactly this: I want to quickly find what would work. After that I'm very happy to take the proper time to go things rigorously.
And please don’t say tests solve that because they don’t. They help but they don’t solve it.
Dynamic languages are very valuable when you can afford to iterate and gradually find out the golden path. For the better or the worse, many businesses are of that type.
That being said, I just ended an Elixir contract and absolutely want to code Go or Rust for money again.
I tend to think more than write code, so usually my first go is reasonably close to what I need. But there are always edge cases you just never think about. I'd rather have a strong debugger than a repl imo
You are unfortunately very correct (at least in my 21 years of experience as well). I too feel annoyance when I know that I made a piece of code work well but (a) every now and then I am truly wrong and (b) various pieces of the system in the code interact in sometimes unexpected ways, unveiling inputs to your code that you haven't foreseen.
So even though it often takes a heavy and annoyed sigh out of me, I still roll up my sleeves and add the tests because I've shot myself in the foot too many times, and ignoring past experience is just being a stupido.
As for debugger/REPL, they are not orthogonal; you can have both. I'd more contrast debugger with tests themselves -- both are ways to go step by step through a process that you know is faulty somewhere.
REPL to me is just a way to more quickly sketch a v1.0 of a piece of code, nothing else.
I'll have to check how does NeoVim fare with these things.
Syntax is easy enough. Like all programming languages, you'll get used to it in a weekend and won't even notice it afterwards.
Elixir is absurdly productive: very terse code, very self-explanatory stdlib API, transparent concurrency / parallelism, and in-OS-process high availability and mostly-self-healing hierarchy of green threads and supervisors observing them.
People on HN and Reddit really love to roll their eyes at stuff that's getting popular, and likely will avoid the technology out of a misplaced spite, just because a lot of people are talking about it. It's a weird phenomena.
(Not saying you're doing it, I just kinda got carried away here.)
with {:ok, id} <- get_id(),
{:ok, val} <- get_val(id)
do
show_success(val)
else
{:error, e} ->
# We reach this if either get_id or get_val fails
show_error(e)
end foo.bar(baz)
becomes bar(foo, baz)
Though you may also need to add in some &s and/or *s, because method call syntax autoref/derefs, and function call syntax does not.https://depth-first.com/articles/2020/09/21/interactive-rust...
https://github.com/google/evcxr
The other option is to use the playground, https://play.rust-lang.org/?version=stable&mode=debug&editio...
Is it meaningfully harder than c++ in this regard?
I'd have an easier time prototyping in Rust than C++, and I've been writing C++ for 10 years and Rust for a little over a year.
However, prototype in something like Ruby (or even TypeScript, and some people mentioned Elixir) is in a different universe compared to C++ or Rust.
Like, it's not even a "fair fight" to compare it meaningfully.
I find that modern C++ "kitchen sink" approach to features makes it good for rapid prototyping, a bit like Perl on the dynamic side. It won't force you into a specific approach, pick the one that gets you there the fastest. Use raw pointers and malloc(), or use fancy smart pointers and RAII, your choice, you can also do both, you have exceptions, you have goto, you can write(), printf() and cout, you have classes and lambdas and (multiple) inheritance and traits. More options are better for rapid prototyping.
Also, C++ is the most popular language for competitive programming, you can't get more "rapid" than that.
Now that I say that, I guess someone could write an "unsound helper functions" library that helps you write code full of UB conveniently. It could be an interesting thought experiment. But I don't think the community would be very happy about it...
If it fits the borrow checker well (like in CLI apps, stateless servers, data transformation) then the borrow checker fits beautifully and seamlessly.
In other settings (complex turn-based games, some compilers, GUI), the borrow checker can cause some artificial complexity and prototyping slowdowns compared to other paradigms.
In fact I like Rust for prototyping precisely because I don't yet have tests, and the extra compiler diligence frees me to focus on the prototype.
I don't think that the parent comment implied prototyping in dynamic languages but rather in statically compiled ones.
FWIW in C or C++ you don't have to do as much code gymnastics to satisfy the compiler so consequently prototyping is both faster and easier when compared to Rust.
I've seen way too many half baked attempts at making prototypes fast that do end up in complete rewrites.
Go tell that to a C++ programmer!
;)
When I open something up to read it, to try and understand it, to dig in and fix something broken… having everything be exposed in the explicitly written code… is vastly more useful to me than trying to mentally interpret a language as I read it and remember the rules, the meta-programming rules… and all the implicit stuff that can affect how the program will behave.
Lot of programming languages aren’t good at this explicitness, and I’ll be honest, it’s a genuine struggle for me picking up the languages like this, only made worse when the documentation is very prose like and fails to convey how anything actually works, eschewing that in favour of, at length, demonstrating the feel of a programming language through countless demonstration example that lack mechanical “what is this doing under the hood” explanation.
Rust may influence us into patterns that are better in some (likely even most) situations, but not always. Sometimes the situation calls for other approaches, and that's okay.
Though, people tend to gloss over that C++20 is decently comparable to Rust in terms of semantics and safety, the issue is very few C++ codebases are modern and the footguns are still lurking for the careless.
That said, Rust iterators are very nice and the async story completely mocks the C++20 coroutine nonsense.