Hacker News new | past | comments | ask | show | jobs | submit login
What is Rust and why is it so popular? (stackoverflow.blog)
296 points by xurukefi 38 days ago | hide | past | web | favorite | 275 comments

Over the last couple of months I've been slowly, but steadily playing with Rust. I work on embedded systems and while it's gaining traction only slowly, it feels to me reasonably likely that we'll be seeing non-trivial applications in the next 8-10 years. I doubt that we'll see it used for low-power/resource-constrained firmware, but lots and lots of embedded systems are now bulky Linux boxes with years of uptime, and I can see Rust making inroads there. It's not a bad idea to be ready for this, just in case it turns out to be a revolution.

Honestly, I like it, and for all the non-hyped reasons.

Like ownership. Lots of us in the embedded space aren't so impressed by the extra memory safety because, if you allocate all your memory statically, there are fewer ways to screw things up with references, and it's a lot easier to do bounds checking, so fewer bugs slip in. Not that "even fewer" isn't good, it's just that the impact is less dramatic than in application code.

But: the borrow checker still pesters me about something I've written every once in a while. And every once in a while, what it pesters me about is a data race that would have definitely bit me in the back sooner or later. It has no security implications, I guess, and it wouldn't crash my program, but it's still wrong. Yay!

Or like traits, which are just so refreshingly sane.

Lots of people are hung up on security and segfaults, and spend far less time talking about a far less categorical property: the conventions that Rust enforces make it easier to write correct code. Sometimes it's not straightforward code, mind you, but "works right" trumps "fits in a single line" in my book...

In many ways, Rust is what C++ could have been if it had not been designed by saying yes to everything. I guess it's not there yet, but there's a chance it might be.

On a more, uh, philosophical note, I think it's pretty cool that our industry has been granted a second chance in this regard. We've already been given Ada, and we missed the chance to adopt it on a wide enough scale to make a difference. Maybe we won't miss this chance.

As someone who never much got into systems programming, Rust feels like a breath of fresh air. It makes systems programming way more accessible for me personally, coming from non-systems languages. Learning to write C well is just not something that appeals to me at all.

From mostly an outsiders' perspective, I just don't think C is a very nice programming language. It looks easy to to pick up and it probably is (for some definitions of "pick up"), but I don't think that's a good thing. The language gives you almost nothing. Pointers, structs, arrays, control flow. Not much else. I'm barely exaggerating when I say that all the C code I see looks like a chaotic pointer juggle fest for precisely that reason. The few features and library that it does have come with non-obvious gotchas that will punish you later.

Rust is probably much harder to "pick up", and way more complicated in general, but it's just, uh, more language. I'll take pattern matching, encouraging immutability, functional style programming, trait programming over C's simplicity any day of the week. The safety is extremely nice, but I think Rust's biggest eye-opener for me is that all these "higher level" features are just possible at (close to) the performance of C. That makes it very appealing to me.

> As someone who never much got into systems programming, Rust is a breath of fresh air.

I think that's part of the problem :) Because Rust looks high level it appeals to people used to high-level programming. But once you get into systems programming, the issues are different from high-level programming, and you're less happy to pay for features that solve other problems. What I'm saying is, obviously, a matter of taste, and some people doing low-level programming do prefer C++'s high-level feel, which is also found in Rust. I hope it goes without saying that just programming in Rust -- or C++ -- doesn't mean you're doing systems programming unless you're, say, writing a device driver, a kernel, a GC, a game framework etc.

Part of the problem is that "systems programming" is an overloaded term that means a number of different things. Is writing a web browser "systems programming"? What about a CLI utility like grep? Kernel module? Bare metal on a STM32? Depending on who you ask most of those will get both a yes and a no answer. On a related note, some language are more or less suitable for each of those. Can you write an OS in Java? Yes. Should you? Probably not.

I think one of the previous comments, and others on other forums have things right when they say that Rust is a better C++. Anything you would consider using C++ for is a good candidate for using Rust for. Rust is not a better C though, it's just a bit too high level for that. There are languages that are aiming to be a better C (Zig is REALLY interesting, but very very new right now), but Rust isn't really one of them.

I could very easily see something like an OS aimed at x86 desktops being written in Rust. Desktop systems are beefy enough and the problem space is complex enough that the extra overhead involved in Rust (similar to C++) makes sense. On the other hand if you're doing some bare metal work on something like an Arduino you just don't have enough there to justify the extra overhead and something very basic like C (or assembly, or Zig once it matures a bit more) is probably a better fit.

If you're doing anything higher level than kernel programming, Rust is just as viable as anything else, at that point it's mostly down to personal preference on whether you can deal with not having conveniences like garbage collection or not.

> Can you write an OS in Java? Yes. Should you? Probably not.

PTC, Aicas and Gemalto embedded JVMs for industrial automation can run either with a real time OS, or directly bare metal with Java Real Time JSR.

Android has plenty of Java in it, as of Project Treble it is possible to write user space drivers in Java, something that Android Things supported since the beginning.

MicroEJ has a minimal hardware glue in C, with everything else in Java.

At CCC there was a demo about TamaGo, bare metal Go for USB security devices, then there is also Astrobe with Oberon-07, the new Meadow boards run .NET Standard based OS.

Arduino and ESP 32 support Circuit Python, uLisp, MicroScheme and picoOCaml.

So plenty of systems programming examples with GC.

> If you're doing anything higher level than kernel programming, Rust is just as viable as anything else

I don't think so because it suffers from the same limitation that all low-level languages have, which is that API clients need to be aware of implementation details. Rust sometimes makes that propagation of leaked information automatically via the type system, but internal implementation details -- how allocated memory is managed, whether a target is a subroutine or a coroutine, whether an argument is passed at runtime or compile-time -- still leak in a viral way. It's just that Rust and C++ can look high-level, but they don't behave like high-level languages. But Rust is great for those low-level programmers who like this high-level style and are willing to pay for it.

That's not a limitation of "low-level languages", it's inherent in low-level API's. These two are not the same. You could have a Rust program that interfaces with outside systems only via protobufs over a network socket, or what have you, and it will work just fine. Same for just about any "high-level API" format you could think of. Of course, using such high-level formats comes at an efficiency cost since you have to translate along the way. But other languages are the same, they just hide that step from you.

The program itself is made of components that expose a low-level API, or otherwise you wouldn't use a low-level language. The API clients are other parts of your program. Programs written in low-level languages are much more tightly coupled than languages that support better abstraction (for the price of less control).

You're probably correct, but I think Rust is probably fitting a solid place of making developers used to higher level languages actually -look- at embedded programming. It's an entry point.

Now, for those who get involved enough in it, they might find issues with the language, and that will provide them incentive to get comfortable with C. Or maybe they won't; maybe they'll get turned off at that point, or maybe they'll find making Rust work a better option, or they'll find still another language that is even closer to C, without the holes.

But either way, providing a way to move in that direction without having to immediately accept all the baggage C brings seems like a good thing. It certainly has moved my mindset from "screw embedded unless it's beefy enough I can run Erlang" to "well, maybe; Rust looks interesting". And I figure if I get comfortable enough with looking into the space, I either

Does the travesty that's currently playing out in the IoT space suggest that we now have a shortage of good embedded people or am I reading that wrong?

A tool that gets more decent developers to even look at embedded sounds like it would have been a good thing to have 5+ years ago, but better late than never.

I don't think there's a shortage of good embedded people. A lot of the companies involved in this travesty could afford them, and have access to good candidates, but have no reason to do it. Cheaper and commoditized hardware has lowered the barrier of entry for selling your own stuff, and the lack of regulation means that the consequences for screwing up in terms of security or privacy are basically zero.

What you see happening isn't an accident. There are companies that do excellent IoT work, with excellent people. Many companies that don't could afford to excellent engineers, and have access to a terrific pool of candidates, but their management chooses another way and they're perfectly aware of what they're doing.

(Sauce: am embedded developer, has been involved on and odd in the IoT scene since 2011 or so).

The nice part about Rust is that if you don't want to use a given feature, you can just ignore it. You can totally write Rust in a struct + functions style, just like C.

If you want higher level abstraction only in some parts of your codebase, you can do that too. It's easy to mix-and-match.

Right, like C++.

Sure, but you still get memory safety.

... hence a better C++. If a better C++ is what you want, then Rust is a great fit.

In 1995 people said Java was a "better C++", but it was basically 1991 C++ plus GC (and numerous misunderstandings), minus concrete types.

Rust can do more of the things C++ can do than Java can, but there is a very great deal that can be put in a C++ library that is wholly beyond Rust's capacity.

If you have lesser expectations to capture semantics in libraries, or to use such libraries that do, Rust serves. But the gap will only grow wider.

> but there is a very great deal that can be put in a C++ library that is wholly beyond Rust's capacity.

Just out of curiosity, do you have some examples?

The easy examples involve operator overloading.

Some more subtle would involve template dispatching according to properties of the types operated on.

But just run down the list of features supported in C++, and not in Rust, and think about how they could change how a library interface or implemention would look. Most C++ features are meant for people writing libraries.

Rust has limited operator overloading. You can do common operations like arithmetic, but you can't define symbol soup

For me it is already enough to be high level as Object Pascal (the original Mac OS variant) or Modula-2, let alone what came later.

Although they do have security issues regarding use-after-free.

Yeah, some of the nice things about Rust aren't immediately obvious. Professionally, I use Rust for a few specific things:

1. Rust is surprisingly great for making cross-platform CLI tools and shipping static Linux binaries. Everybody can just install a single executable and they're ready to go. (Go is good at this, too.)

2. Rust is great for anything where I ask, "How big a cluster do we need for this?" I get roughly the same speed as C++, except there are far fewer footguns. And I can add threading support to existing code in an afternoon, and I can expect it to just work.

3. Rust's very new async support is powerful in some very interesting ways, and I have a couple of programs that it has worked beautifully for. (I'm working on an upcoming open source release of one of them.)

4. Rust's algebraic data types (aka "enum" and checked "match") are a joy for any software involving lots of special cases and complex logic. I think every typed, high-level language should steal this feature.

However, I have mixed experience using Rust for business logic. Yes, item (4) above does help with business logic. But business logic changes a lot, and it needs to be accessible to many developers within an organization.

So on my recent team projects, Rust often winds up doing the heavily lifting. But the rapidly-changing business logic will often get deferred to a GCed language. So far, this is working nicely.

From my experience it's quite a good language for fun experiments and coding challenges, at the very least. I grew to love it quickly during advent of code.

The iterators, enums and no Null types lend themselves to interesting solutions.

The crate ecosystem is also developing fast, and there are decent browsable docs and bootstrapping the env and development environment are all easy.

SDL2 support makes it really easy to make rectangle based games like classic pong and experiment with keyboard and controller inputs etc. (never mind further possibilities of 3D etc).

TTY apps and games are also easy to make with the termion crate.

I think it's just kind of worth learning in a way that (for example) Python, C and Haskell are complementary options for learning different ways of thinking about of coding. Rust feels like a different flavour of programming. It's borrow checker and branch checking etc. they really are likely to lead to better programming in other languages too. Understanding ownership and considering the transfer of ownership are valuable.

We’re already using it in production for embedded development (on stm32 MCUs). So are a lot of other people. It lets you target a niche between spaghetti code on bare metal and structured and full-blown runtime/framework, making something along the lines of reusable libraries for bare metal without a runtime or OS possible via its zero-cost types.

I think that Rust's approach to safety -- soundly eliminate UB in safe code -- comes at the high cost of complexity. This affects how easy it is to write custom compilers (very important in the embedded space), but it is also not necessarily the best way to reduce bugs. For some, this cost is acceptable, and I'm sure some people may even welcome the high-level-looking code [1] that Rust and C++ support, but I think there are better ways, ones that are more appealing in low-level ("systems") programming in general and the embedded space in particular: https://news.ycombinator.com/item?id=21970987, https://news.ycombinator.com/item?id=22021237

Rust is without a doubt a (much) "better C++" but I'm not sure a better C++ is necessarily what systems programming needs most.

[1]: Not that writing that code is as easy as in a high-level language, nor does it offer the same level of abstraction as high-level languages, where changing the details of the implementation does not affect the API and its clients, but it looks high level, or "expressive", on the page.

> This affects how easy it is to write custom compilers (very important in the embedded space)

Is there a reason you’d write your own Rust compiler frontend, rather than just letting rustc generate LLVM IR as it does, and then writing your own LLVM arch target? None of the Rust complexity leaks over into the LLVM IR it generates; it looks just like the LLVM IR that e.g. clang generates.

> None of the Rust complexity leaks over into the LLVM IR it generates

The leakage even triggers performance issues in compilers: https://users.rust-lang.org/t/5-hours-to-compile-macro-what-...

No, that's not "Rust leakage", because that misbehavior has nothing to do with the semantics of Rust as a language. That's the effect of some non-optimized function-scope-level pattern-matching substitutions that LLVM is applying, as applied to the user's very large function body. Quoting a reply in that same thread:

> LLVM is not good at big functions, I have seen this before as well. One of the functions you are generating is almost 100,000 lines of Rust code including tons of internal control flow.

The same would happen if you wrote (or generated) 100,000 lines of C in one function body, and fed it through Clang with -O2.

If you're wondering, there's nothing in rustc that makes it implicitly turn regular code into huge function bodies, either. It's just someone abusing Rust macros to codegen badly, not taking into account how the granularity of units of compilation interacts with the time-complexity of optimization passes.

> that misbehavior has nothing to do with the semantics of Rust as a language.

Macros are part of the language; they aren’t an external code generation tool.

> The same would happen if you wrote (or generated) 100,000 lines of C in one function body

Absolutely, but neither C nor C++ makes it easy to generate such code. Technically doable with C preprocessor, but it’s not easy. C++ templates don’t normally expand into 100k lines functions either, they can easily expand into 100k small functions.

People write code generators that emit C/C++ code all the time, and 10KLOC functions coming from such a generator isn't unheard of. The x86 instruction selector LLVM generates from tablegen is over 240KLOC, although that's emitted effectively as an interpreted table, so the actual code size of the function is much, much smaller.

You’re correct that it’s possible to trigger that performance issue without Rust.

However, it doesn’t happen with idiomatic C or C++ code. C macros are too hard to use for that. C++ templates are designed to expand into many small functions, as opposed to a single huge one.

It was Rust complexity leaking over into the LLVM IR.

> C++ templates are designed to expand into many small functions, as opposed to a single huge one.

...so are Rust macros. The user was using Rust macros very non-idiomatically.

Also, you don't use C macros to write (large amounts of) C. 90% of the world's generated C, by volume, comes from, I would say, one of two programs: autoconf (through m4), or yacc. And both autoconf check stanzas and yacc's inline C support are easy to screw up in ways that result in horrible code that makes compilers barf.

Also, to be clear, you're conflating two things with the phrase "Rust complexity." This thread was originally about the difficulty of implementing a Rust compiler for a toolchain, which therefore makes "Rust's complexity" here refer specifically to the complexity of the static-analysis semantics of Rust that make writing a Rust compiler frontend difficult.

The solution—relying on the existing rustc frontend for the "hard stuff", and just implementing your own compiler backend to target the embedded architecture—is not rebutted by a claim that you can write bad Rust code that makes the optimization passes of certain compilers choke. You wouldn't even be writing optimization passes. You'd be writing a backend. The optimization passes are universal. It's the job of the LLVM developers to ensure that they don't choke on things like this.

And, despite the fact that 100,000-line functions are dumb, it's the LLVM development team's fault that the optimization passes were written in such a way that their time-complexity is superlinear in a way that stalls out when optimizing a function like that. It's not up to the Rust compiler authors to not emit that type of code, or to somehow prevent you from writing it; it's up to the LLVM devs to make their optimizer work, and work efficiently, for any "valid" code. Honestly, if anything, this code—if you could get it—would be a great integration test to submit to LLVM, for them to work towards passing.

At the scale of macro complexity that occurred in the Rust code, you would be dealing with autogenerated C/C++ code. Autogenerated C/C++ code of that complexity absolutely exists in practice.

The problem here isn't Rust's complexity; it's autogeneration taken to the extremes without concern for its impact on compile time. The fact that Rust provides builtin macro syntax to do this autogeneration is of little importance, since it will happen just as frequently with external build tools in the C/C++ world.

> Rust is without a doubt a (much) "better C++" but I'm not sure a better C++ is necessarily what systems programming needs most.

As an embedded consultant, a better C++ is what systems programming needs most not for technical reasons, but social. So many embedded shops are embracing C++ and it's causing all the sorts of problems you might imagine. While it's possible that these shops will tack back towards a lower-level language, my prediction is that would be a much harder sell than something like rust.

The problem is that Rust doesn't solve C++'s problems (my top two: language complexity and build time), it just brings fewer of them with it. I think that C still rules the embedded space, but those that switch to C++ might not do it because they love its (and Rust's) approach so much as they need to do things that C does badly (partial evaluation and polymorphism). There are other languages out there that address those concerns without C++'s or Rust's complexity.

You've been asserting this for a while now, without really describing what you mean by "Zig's approach." What features are you thinking of here, and why would we expect them do any better than existing tools in C++ (or even C)? For example, "modern C++" is also often described as having similar benefits to safety.

Zig's approach to safety is to optionally add runtime checks either in debug builds and/or in arbitrary code scopes even in product builds, rather than to try to soundly eliminate them. This means that the language can be drastically simpler. Some UB can escape this kind of unsound safety, but on the other hand the simplicity of the language makes the semantics of an expression easier to understand -- which may make, say, code reviews cheaper -- and may free up time for other kinds of assurance, be it through faster compilation, shorter development cycles, and possibly static analysis tools, that generally like simple languages.

Now, note that I am not saying that Zig's approach to safety is definitely better than Rust. Correctness is an extremely complex issue, with many factors, and it's hard to say with any certainty what works and why. My preference for Zig (which is largely hypothetical as Zig doesn't really exist in a meaningful sense yet) is because I personally value language simplicity and short cycles over what some call "expressivity", but as someone who is also very much interested in formal methods and software correctness in general, I am not convinced that Rust's complexity buys you increased correctness over Zig, and it may even be worse. So the tradeoff is simplicity vs. "expressivity", where correctness can go either way.

C and C++ have plenty of analogous checks- debug assertions in the standard library, runtime checks for uninitialized memory, sanitizers, etc. Do we have an idea how effective they are there? Do we have reason to expect Zig's to be any better?

In fact, Rust approaches most of these particular problems the same way- arithmetic overflow, array bounds checking, stack overflow handling, etc. are all checked at runtime. Rust's language complexity is dedicated to things that Zig simply doesn't check, and that C and C++ have checked only recently.

This goes back to a previous conversation of ours[1]- Rust's complexity is allocated very differently than C++'s. It has many of the same advantages as Zig (if not more) when it comes to understanding and code review. Painting Rust's static analysis and associated language complexity as an alternative to C/C++/Zig-style runtime checks looks like a category error to me.

[1]: https://www.reddit.com/r/programming/comments/eehe6t/a_backw...

> C and C++ have plenty of analogous checks- debug assertions in the standard library, runtime checks for uninitialized memory, sanitizers, etc. Do we have an idea how effective they are there? Do we have reason to expect Zig's to be any better?

Yes. Take a look at some of the checks Zig has.

> Rust's language complexity is dedicated to things that Zig simply doesn't check, and that C and C++ have checked only recently.

Right, but that doesn't mean it leads to more correct programs when this "checking" comes at a cost.

> It has many of the same advantages as Zig (if not more) when it comes to understanding and code review.

That's a matter of taste. Those who like complex languages like, say, C++ or Scala, can certainly prefer them, but I think they're in the minority. Zig is a very simple language, while only C++ and Scala contend to be as complex as Rust or more.

> Painting Rust's static analysis and associated language complexity as an alternative to C/C++/Zig-style runtime checks looks like a category error to me.

If you, like me, don't particularly like complex languages, then the complexity has a cost. What does it buy you? It buys you certain sound guarantees about lack of UB is safe code, which hopefully helps write more correct programs. If you have an alternative to achieving a similar level of correctness with a much simpler language, I would very much prefer that.

> Take a look at some of the checks Zig has.

I did, to make sure I wasn't missing something. There's nothing new there, and some things are missing. (This is not bad, Zig is still in development, but it's not exactly a new approach either.)

> only C++ and Scala contend to be as complex as Rust or more. ... If you, like me, don't particularly like complex languages, then the complexity has a cost.

This is why I linked our Reddit conversation- Rust is nowhere near as complex as C++, and its particular complexity's costs are not difficulty in reading or code review.

> If you have an alternative to achieving a similar level of correctness with a much simpler language, I would very much prefer that.

But this is exactly my point- I don't believe Zig is such an alternative! Zig and Rust both improve over C and C++'s complexity and readability, leading to some general correctness improvements; so far only Rust does anything different to address memory safety.

> There's nothing new there, and some things are missing.

And it still goes further than C sanitizers (except the glaring missing piece of use-after-free, which I'm sure will be addressed).

> Rust is nowhere near as complex as C++

It's hard to quantify this, but I think few people would point at any language (in real use) other than Scala, C++ and Ada as being as or more complex than Rust, so it's at the very top. Some people are perfectly OK with that and even prefer such languages. Rust is well beyond my language complexity comfort level (even C# is too complex for my taste, and, as a high-level language it offer much better abstraction than Rust, or any low-level language). So if C++ is at 500 and Rust is at 300, that doesn't mean much if I want to be at 50 or 100.

> Zig and Rust both improve over C and C++'s complexity and readability

I don't see it this way. I find it hard to put C and Zig in the same category as Rust.

> so far only Rust does anything different to address memory safety.

I disagree with that, too. Rust is the only one that addresses memory safety using sound guarantees. If you run tests on a Zig program out of the box you won't have array overflows; that's not what you get in C and C++. Zig's "big idea" or "doing anything different" is how it does partial evaluation with a single construct (comptime) that is drastically simpler than anything I've seen. In other words, as far as simplifying languages with tough requirements for low-level programming, it's rather revolutionary. That's my preferred direction for programming languages.

> If you run tests on a Zig program out of the box you won't have array overflows; that's not what you get in C and C++.

Build a C program in the right mode (also required for Zig) and you get exactly the same thing.

What mode would that be? The various fsanitize options? C doesn't have slices. Zig also allows turning on safety on a scope level. Not to mention the powerful comptime polymorphism/introspection mechanism that allows working in a more typesafe manner than C, while still being much simpler than Rust.

I don't see how Zig comptime is any simpler than Rust. Frankly, it seems more of a kluge. But we've already been over this before. :)

A single construct does the work, or most of the work, of generics, value generics, const fn, traits, attributes (although I expect some form of attributes might be added to Zig) and macros, and it does so without type-level programming or macro-level programming, both their own mini-languages. A kludge is in the eye of the beholder, but one is simpler than five or six.

That's hardly an honest comparison. I can just as easily split comptime into "type comptime," "value comptime," "comptime blocks," "builtin functions like @isInteger," and "inline control structures" (that one doesn't even use the "comptime" name!).

Arguably this combination is more complex than Rust's. It has no way to constrain a comptime type argument (traits), so you get error messages like C++ templates. It has no way to constrain a function to be comptime-compatible (const fn), so you get more error messages like C++ templates. When you want to combine things, you manage phase ordering and idioms by hand, basically re-implementing Rust-like concepts at every use site.

Sometimes one or two more concepts in the language makes things simpler. To use a subject you've discussed before, it's similar to scoped continuations vs full call/cc.

> I can just as easily split comptime into

In Rust, generics, macros, traits, compile-time evaluation are different constructs with drastically different syntax (and generics and value generics are different features, implemented at different times, but I can accept them as a single construct).

> It has no way to constrain a comptime type argument (traits)

It does: introspection, just as Clojure can constrain arguments, only Zig does it at compile time.

> so you get error messages like C++ templates

You don't because in C++ templates are programmed in their own sub-language with SFINAE tricks (at least in the C++ versions I use; they've probably added new ways to do this, as they do). In Zig, it's just Zig computation. You'd get similar compile-time errors as you would get, at runtime, in, say, Clojure or Python.

> When you want to combine things, you manage phase ordering and idioms by hand, basically re-implementing Rust-like concepts at every use site.

You don't need to reimplement things by hand at every use site; you just call a subroutine at compile time.

> Sometimes one or two more concepts in the language makes things simpler.

I agree, but I think that Zig's comptime brings revolutionary simplicity to the very complex subject of partial evaluation which is so important in systems languages. How well it would work in practice remains to be seen, and I may well be disappointed, but I find Zig's approach of simplicity first very appealing. I agree it's a matter of taste.

> ... generics, traits ...

Again, these are just as much a single feature as Zig comptime. Traits are like comptime types, or else (closer to what Zig does) comptime type variable introspection.

> You'd get similar compile-time errors as you would get, at runtime, in, say, Clojure or Python.

Exactly- you're not writing plain Zig, you're writing a Zig-adjacent dynamically typed language with new ways to do almost everything and different tradeoffs around correctness.

> just call a subroutine at compile time.

Whoever wrote that subroutine did the reimplementation by hand.

You're looking at this differently from me. The way I see it, Zig is not, say, C, with an extra compile-time language to replace macros. It's a simple dynamic language, with optional typing, where you select which code runs at compile time and which runs at runtime. Aside from being quite revolutionary in that respect (precisely because the compile-time code doesn't operate on the AST, like in Lisp, but on program objects) -- languages like Nim and Zig have a similar feature, but they also have other features -- it has certain big practical implications. For one, you could imagine stepping through a Zig program with a debugger at compile-time, seeing how it operates on Zig objects, not produces an AST that goes through another stage. For another, in terms of program semantics and analysis, the program means the same thing as if the language were truly dynamic and everything was evaluated at runtime. I.e. Zig has the semantics of a very simple dynamic language. So the subroutines that run at compile time and that you or someone else writes, are just simple Zig code you can read (and maybe, some day, step through).

Rust has procedural macros too. And they're not a separate "mini-language" like the C++ template hacks, they just use Rust itself, except with a phase separation involved since they run at compile time.

This is worse. Feature-rich languages like C++ and Rust always end up adopting pretty much every nice feature from every other language. The trick is to have fewer features, not more; at least that's my aesthetic preference. In other words, brag about the features you don't have, not the features you do :)

As someone who is using procedural macros in my crates: they are nowhere close to as powerful yet as Zig's compile time evaluation. For example they cannot be used in expressions in stable Rust without ugly hacks yet, and the tools for generating the new AST are quite clunky and hard to write fast code for.

In C++17 and moreso in C++20, doing C++ template hacks is only excusable for legacy code, or trying to make code portable to older compilers.

> Rust is without a doubt a (much) "better C++" but I'm not sure a better C++ is necessarily what systems programming needs most.

I agree but if better C++ is what the PL industry can give me, then I'll take it, thank you very much!

(Frankly at this point I'll take anything that isn't C++...)

There are alternatives that more appeal to my taste in the works. Given the cost of changing language, any language, I'll wait and see how they turn out before making decisions.

Which ones are more to your taste? For me it is mostly Zig which seems closer to what I want to see in a language. Crystal also looks promising but I prefer languages without GC. Rust is a good language but it is a bit too complex and restrictive at times.

Yep, Zig is the one I like, and IMO it's a language that shows an interesting yet very simple model for what systems programming can be. But I'll admit that it's easier to look good before you're put to the test in the field, so I'll wait and see what becomes of it.

As far as I can tell Zig is equivalent to a subset of C++ and thus completely lacks all the guarantees that Rust provides and several of the features that C++ has; so there is no point to use it instead of those languages.

If you prefer languages with more features, then simple languages aren't for you. But me? If you told me you'd give me language X but with far fewer features, my eyes would light up, and I'd only ask, are you sure you can't get rid of any more? As Saint-Exupery said, "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." Zig has all you need to write clear, efficient, generic, systems code and nothing more, but also nothing less. It is also intended to help you write safe code, but it goes about it differently from Rust.

As far as I can tell Zig only has C-like malloc/free-based allocation and thus is vulnerable to use-after-free, and so does NOT help you write safe code.

It also doesn't seem capable of safe concurrency.

You assume that the only way a language can help you write safe code is by making sound guarantees; this is wrong. A language can also help you write safe code by making it easy to selectively add runtime checks (that can then be selectively turned off in production), by making code-build-test cycles faster, and by making it easy to inspect what the code does. This approach has tradeoffs: it is unsound so it will let some undefined behavior bugs through; on the other hand it might do more to reduce bugs that are unrelated to undefined behavior.

> it is also not necessarily the best way to reduce bugs

I think this needs to be more specific. Comparing Rust and C, for instance, it seems complexity can be used to improve correctness; the tradeoff is worth it at least some of the time.

It seems to me the best example of a simple correctness-oriented language isn't Zig, it's Ada SPARK, which has been used in various life-critical software systems. [0] SPARK's advantages are due to its simplicity:

* The whole language has been defined formally (zero ambiguity)

* The language is amenable to formal verification

A monstrously complex language like C++ brings many features, but is much harder to reason about formally, and will never have a formal definition.

[0] https://en.wikipedia.org/wiki/SPARK_(programming_language)

> Rust is without a doubt a (much) "better C++"

Huh? They are apples and oranges.

Is Rust intended to provide "Direct mappings of built-in operations and types to hardware to provide efficient memory use and efficient low-level operations"? That's one of C++' design goals.

If you change the design goals, you get different advantages and disadvantages.

See more about the C++ design goals in this interview:


Yes, this is a design goal that they both share, and generally accomplish in similar ways.

> I doubt that we'll see it used for low-power/resource-constrained firmware

I'm curious what your reasoning is for saying this?

It's mostly a hunch, based on a combination of lots and lots of factors. It's very difficult to explain. From a distance, "embedded" looks like a very homogenous field, but it's nothing like that. Some of the factors that contribute to this hunch -- but bear in mind that they don't apply everywhere in the embedded development space, nor equally, nor to every kind of device -- include:

1. A lot of resource-constrained firmware is so straightforward that Rust's benefits simply don't justify the effort of learning it and using it. In turn, without sufficient demand, there isn't much motivation for large tooling vendors to get into the game. Without the large tooling vendors, the kind of companies whose money could shift the landscape significantly won't get in the game, either.

2. Lots of embedded software development is outsourced. The margins are pretty small, and the companies in this field are both unwilling and unable to build technical expertise early on, so there's a lot of inertia.

3. Lots of embedded software is developed based on manufacturer-supplied SDKs. Manufacturers in this field tend to run high-inertia, cost-conscious software teams that take a long time to catch up with the rest of the software industry.

4. A lot of this inertia is mistaken for prudence ("we value stability", "we don't just jump on the hype train") and touted as a positive thing. That's why IoT security is what it is, for example (and it's not just IoT, and not just security. Lots of areas in the embedded space suffer from terrible practices). This is an industry where an embarrassingly large number of companies are just discovering continuous integration. A whole new programming language won't just happen overnight.

5. Lots of resource-constrained firmware is written with pretty strenuous regulatory constraints in place, under considerable pressure from internal standards, audits and so on. In some regards, Rust's tooling ecosystem still needs to grow and mature. AFAIK there's no serious equivalent to Coverity, for example -- and plenty of companies value it not just for the analysis it makes (which doesn't mean as much as it seems because the Rust compiler does a lot of static analysis on its own), but also for the kind of traceability and integration that it gives them, and the ability to implement the kind of internal processes that look good on paper during an audit.

It's a mix of legitimate and non-legitimate concerns (specifically, #5 is very legitimate -- lots of internal processes are just software safety theater, but many aren't).

Very interesting breakdown.

Do you think that Rust could instead help outsourcing? Similar to how Java's GC keeps teams away from segfaults, could Rust's safety guarantees give companies more confidence that an outsourced team's code would have fewer critical bugs?

Uh, I don't think I can answer that question objectively. My opinion about outsourcing companies is heavily influenced by the fact that I am from one of those cheap outsourcing destinations, and it's anything but positive. (Edit: to clarify -- I have first-hand experience with outsourcing so yeah. Not positive.)

I guess -- but take it with a grain of salt, given what I've said above -- that it's something which shouldn't even play a role in deciding whether to outsource something or not. There are infinitely many ways to introduce critical bugs, and Rust -- any language, in fact -- helps with only a tiny subset of these. It won't help you against misusing crypto primitives, or failing to validate paths, or a bunch of other things.

(Edit: I guess what I'm saying is that, if you don't trust a development team to get something done in a language, you shouldn't trust them to get something done in any language. Bugs can happen in any language, and some languages make it easier than others to introduce some types of bugs. But good developers should be able to write good software in any good language, it's not like we're comparing Rust and INTERCAL).

Also, Rust is pretty complex, and it attempts to solve a lot of non-trivial problems. In my experience, attempts to handle this kind of complexity by organizations that focus on nothing but price and headcount misfire very, very badly.

Java doesn't keep teams away from NullPointerException, ConcurrentModificationException and CrossCastException - Rust does. But then, think of the amount of serious bugs and design flaws that typical Java/.NET outsourced code has, even after the former have been scrubbed away from a codebase. Let's just say that I'm far from optimistic that Rust alone could be the silver bullet that makes outsourcing work.

Are you going to use Rust on a PIC12 with 32 bytes of data memory and max 256 code instructions? Of course not. Assembly is still king in this low-powered embedded class and will stay as such for the foreseeable future.

But the full quote is: "I doubt that we'll see it used for low-power/resource-constrained firmware, but lots and lots of embedded systems are now bulky Linux boxes with years of uptime, and I can see Rust making inroads there."

There is a massive number of devices between an 8-bit PIC and a Cortex-A. Obviously you're not going to use Rust on a tiny PIC or similar, hell that architecture is outwardly hostile towards even C. I'm guessing these very low power chips will exist for many years to come, but a lot of work has moved over to things like Cortex-Ms which absolutely benefit from things like Rust.

Yeah, this segment (Cortex-M) is on the order of a billion devices shipped each year. With growth expected to stay high for years to come. Plenty of space for Rust to get adopted.

Maybe I misread it, but it sounded like the OP was comparing Rust to C or C++ on low-powered/resource-contrained firmware, not assembly.

At the 10 year horizon the grandparent was using, the ultra low end of MCU may be substantially more powerful, with possibly lowend AM or RISC V being the smallest thing you can find. At some point, packaging will dominate cost over silicon for such small MCU so a better silicon won't cost much more...

Packaging will dominate silicon costs? I see plenty of silicon chips directly soldered onto PCB's for the smallest and cheapest applications, i.e. no packaging whatsoever.

The entity that solders it received it on a tape most likely, in 10 year I can totally see a small 32 bit core costing less that that.

I interpreted alxlaz' comment as Rust vs C (or other high level language, C+" etc...), which his answer to my question seem to indicate that was the case, as he gives more reason for Rust likely not to be adopted on some platforms.

In that specific case, I’d probably still not use ASM directly, but rather probably a Lisp DSL for machine-code generation (and a Lisp emulator for the ISA it generates), so that I could in turn write some genetic algorithm or somesuch to explore the space of such ASTs (and thereby the space of max-256-byte machine-code programs) to find the optimal way to pack instructions to solve my problem (where “solve my problem” is specified in terms of what the emulator’s registers and memory should look like on a given cycle.)

ASM is for the use-case where you're optimizing code in terms of using specific instructions or intrinsics; but it's not really for the case where you're concerned with specific opcode encodings (as ASM abstracts that away, grouping multiple different opcode encodings—some short, some very long—behind a single friendly instruction name.) In that case, you have to work with the machine-code directly—or, at least, through data structures that contain machine-code at the base level, and so can tell you exactly what machine-code they contain.

> lots and lots of embedded systems are now bulky Linux boxes

These systems have the resources to run managed runtimes. I’ve shipped embedded software running .NET core 2.2 on ARM Linux (RK3288 with custom set of peripherals), only a minor part of the software being unsafe (a shared library written in C++).

Over the last 20 years, desktop GUI software, web servers, and mobile software migrated from C++ towards managed languages, and they never looked back. I’m pretty sure the majority of embedded software gonna follow the same path.

I work in the embedded space, but the majority of my work is writing simuators, mathematical models and tests. One of the hidden benefits for us was that rust is suitable for both resource-constrained embedded code (we use a lot of C for this) and high-level desktop and cloud based infrastructure/sim/test code, which we would never consider writing in C. Serde is amazing, crates.io has so much good stuff on it, C interop is a breeze. We still use Python/matlab for exploratory and data-sciency work, but as soon as something lives for more than about 6 months, it usually gets re-written in rust.

Now switch to Julia instead of Python/matlab and you have a really solid stack.

Julia lost its momentum, and for good reasons: insuficient or rushed up libraries, no option for the generation of standalone executables and general overselling (by the way, bashing Python at every opportunity didn't lead to a higher volume of users)

It didn't lose momentum.

I think one of the biggest benefits of Rust is it bakes in static analysis of code as a first class feature. Which means the language is amenable to analysis and you don't have to use third party tools to benefit from it.

I also like some of the abstractions. They're clever in their simplicity. For example, an iterator over an array or vector is simply doing a for loop using pointers.

Yes and no. It provides some kinds of (important!) static analysis out of the box, but at the cost of complexity, which directly adversely affects some other kinds of (also important) static analysis. For example, there are sound static analysis tools that guarantee no undefined behavior of C code, but AFAIK, such tools can at best only work on a subset of C++, because of its complexity.

Rust goes all out on eliminating undefined behavior, and may well be the best way of doing that in low-level programming, but eliminating UB is just a means to an end, UB is not the only source of dangerous bugs, and if the cost of eliminating it is high it may not be the best way overall of reducing bugs in low-level languages.

What is the complexity, and what are its costs? As an active user of Rust, I haven't seen the (adverse) complexity or its costs yet.

It's worth pointing out that Rust combats more than undefined behavior. Undefined behavior is a category of bad things that Rust works to eliminate, but Ownership goes beyond eliminating UB, and eliminates a large swath of potential logic bugs.

Programming in Rust is complex, I'm not sure how can argue against that, it is not straight forward to do simple tasks because of how you need to organise your architecture with the borrow checker.

Most people that starts using Rust get stuck on issues that you woudn't have with other languages.

In my experience the difficulty of picking up Rust is most pronounced for people experienced in other languages that have common design patterns that are discouraged or made impossible by Rust. It's harder to unlearn something that from your point of view works (even if it had hidden or clear drawbacks) when you're also having to learn other things simultaneously. Also, I feel the biggest hurdle Rust has for experienced developers from other languages is that Rust makes some ineficient code visible, but the way of optimizing it requires delving into more advanced parts of the language, frustrating people when they are most "vulnerable". This is where the common piece of advice for people starting with rust "just clone for now and don't think about it" comes from: get used to the language first and deal with borrowing on its own at a later time.

But all of this frustrating learning curve comes to fruition later in when writing code because the experience is closer to pair programming with the compiler rather than trying things in a vacuum on your own.

> Programming in Rust is complex

Make a distinction between programming and the overall programmer experience. C++ is not a simple language and it feels like some of the the rules are arbitrary, vendor dependent, or for the same of backwards compatibility.

When programming C++ at scale you start dealing with manifest files. Different understanding of C++ (templates/precompiler? exceptions? std? the list goes on).

Rust on the other hand is mostly pleasant. Sometimes I have problems with cargo. However like C++ build systems made life legitimately miserable sometimes.

I'm really excited for Rust. I think that at some point it might replace large parts of the OS. I can imagine important parts of the internet (DNS servers, caching servers etc) running on raw hardware. Your OS eats too much of your perf.

You are right, some parts of Rust are tricky (still working out proc_macros) however you get a lot of power from these.

It also feels like the Rust team really thinks ahead.

Like C++ is still working on the Range type. Originally, it was supposed to be in C++03 but that didn't happen and here we are 17 years later still waiting.

You can say things like that the type system doesn't support higher kinded types and such. You are right and I think that at some point, Rust will get them, right now there are more important battles. Whoever manages to implement them will be crowned the king of Rust I'm sure.

It’s not that simple. Rust’s rules also make more complex tasks specifically easier, at least for me. YMMV.

The "rules" that the borrow checker enforces are the rules of functional programming, except in an extended form that adds flexibility to many tasks as opposed to removing it. The main point is to not share and mutate objects at the same time, because that comes with inherently unclear semantics and a high potential for bugs. (Rust has mechanisms for shared mutability, but even those trigger runtime checks to ensure you aren't actually doing anything that would be bug-prone in that way.)

> sound static analysis tools that guarantee no undefined behavior of C code, but AFAIK, such tools can at best only work on a subset of C++, because of its complexity.

What tools are these, and why haven't they been deployed across every C codebase to prevent memory safety bugs?

E.g. Trust-in-Soft, and while they're cheaper than a rewrite in Rust, and so they're also used more than Rust, especially in safety-critical software, they do require some effort. I don't know how much "every C codebase" is willing to spend to become UB-free.

Also, ownership checking only seems to work well for tree-like datastructures, but implementing something with cycles (back-pointers) immediately leads to nasty problems.

That's not a problem with Rust, it's a problem with back-pointers. You basically just need to fall back on raw pointers and do all the correctness checking yourself, precisely because the ownership model is not that helpful here. (Although if there is a pattern of "owning" references which involves no cycles plus back-pointers that are actually identifiable as such, that is directly supported via Rc<> and Weak<>.)

Hum... UB is a huge source of analysis complexity. If are not comparing it with an insanely restrictive dialect of C (that will bring a lot of code complexity by itself), or I will love to see those static analysis tools that are better than Rust's.

They're not "better" than Rust (I'm not even sure what that means), but they're cheaper, and that's why they're more popular. I'm referring to Trust-in-Soft (the people behind Frama-C) and some other similar tools, although I now see that TiS say they support all of C++11.

I'd like to understand what you mean by baked in. Not only does vscode need a plugin, it needs a language server running to do the static analysis. Are there analysis capabilities without the language server?

I believe he means that certain things that would need static analysis in other languages are impossible to do as part of the type system.

For example match statements need to be exhaustive. Your program won't compile unless they are.

Not Impossible, but have to explicitly makred as "unsafe"

The other important aspect is that even if you have a static analyzer available, people might not be able to afford them (Coverity/klockwork/etc licenses) or even if they have it, there is nothing preventing them from skipping the analysis (just for this one time, I promise). (Another trick is to run the static analyizer, and not fixing the issues found...)

With Rust the compiler is already providing a lots of analysis, and you can't easily skip it. And if you do by using unsafe{}, it shows. So basically, even if your dependencies are provided by the worst team in the world, you know that the guarantees enforced by the Rust compiler are in the code. (To be fair, it does not mean that the SW will do anything useful, but it won't likely segfault)

The compiler by its self can do it, if you run it.

I believe the language server is just for real time editor integration.

Gotcha, thanks. This is too tangential to belong here. I need to go better understand what exactly the language server is doing if the compiler is able to provide all the details. Going to guess it has to do with partial/progressive analysis and supplying a programmatic interface to convert errors/warnings into squiggly lines rather than text output.

> I need to go better understand what exactly the language server is doing if the compiler is able to provide all the details.

Converting it from what the compiler knows to the https://langserver.org/ protocol.

The long-term goal is to have the compiler be able to do this directly, but there's some stuff to do in the meantime.

vscode requires languages to implement a language server. It doesn't have anything to do with rust.

> it bakes in static analysis of code as a first class feature.

This is basically what all type checking does. It's not specific to Rust.

Rust brings more to the table than just the standard static type checking, you're selling it short.

The borrow checker is unique to Rust. So is compiler enforcement of only allowing thread safe data structures to cross thread boundaries.

Both of those are a pretty big deal.

Because the StackOverflow survey which Rust keeps winning defines "Most Loved" as:

> % of developers who are developing with the language or technology and have expressed interest in continuing to develop with it

Because there aren't that many Rust jobs, almost no one has to use it. Which means people either try it and leave, they like the language and stick around, or they never use it (the overwhelming majority of developers). This leads to the Rust being the most loved language by the above definition, which is completely different from "popular" (as in the title of the OP).

If I make up my own language that I plan to never stop using, even if no one else ever touches it, I'll get 100% "Most Loved" on StackOverflow's survey.

Yup, which is what I alluded to with "However, the roughly 97% of survey respondents who haven’t used Rust" :-)

Well, yes. There are plenty of popularity metrics there already, this one is about something else.

As you said, mainstream languages won't win this one. But it is a valid metric anyway, and there is plenty of merit on winning it.

Think about this - if a bunch of people hate a language and stop using it, the following year that language's "most loved" score will increase. I wouldn't call that merit, it's just a bad metric.

Yes, if people can simply stop using a language, it will not be hated. That's how it works on real life too.

But most of the time, people can't stop using languages.

Rust is a great language if you use for what was intended, system programming and as safe substitute of C and C++.

But it's not the answer of everything, to me it's nowadays abused in a lot of projects, there are instances of project where using Rust not only doesn't make a lot of sense but also can be slower than another languages, there are cases where Go is better, other where Node.js is better, other where Python is better, other where Java is better, etc. To me the Rust community seems to want to argue that everything should be rewritten in Rust, just because Rust solves every problem, while it's not.

The key is in another comment on this thread:

> Lots of these things that look like syntax problems are in fact design problems surfaced by the compiler.

A lot of people are finding value in the rules Rust provides. This is irrespective of domain. The strict compiler helps you refactor code in ways that less strict languages don't. You still can do it, of course, you just have a lot less help.

The trick is, is the initial hit in productivity worth it, until you get up to speed?

That said, of course everything doesn't need to be in Rust. But there's a reason it's finding broader appeal than purely systems stuff.

I think this is misplaced causation. Don’t discount the fact that a significant number of programmers just like novelty and like Rust because it’s new in the same way Haskell is new to a Java dev.

That said, Rust’s domain does seem wider than just systems programming. It has the right abstractions to be suitable for (edit: some) higher level things like web apps.

Personally Rust is turning into what I was assuming and hoping Go was going to turn into back in 2010: a static language that does most of what we all used dynamic languages for, without too much extra difficulty. (That is, after you get used to the borrow checker’s rules.)

> higher level things like web apps.

Frankly any language that makes me write "some string".into(), and all of the other nonsense of Rust, is not suitable for writing string processing applications (as opposed to utilities, such as ripgrep). The business logic of any Rust application that deals mostly with strings is hopelessly obtuse and/or obscured. Languages like Perl, Python and Ruby, or even JavaScript and Java, are more suitable.

Rust focuses on and succeeds at being an improved C++, no reason to use it for everything.

If "some string".into() is your #1 complaint you haven't used Rust enough

Web frameworks convert strings to business logic, web apps deal only in business logic. Fortunately the web framework is only written once to support multiple web apps.

That sounds nice, but practically a lot of web app development can't be perfectly modeled by a type system. There's a lot of string munging and bashing, because at the end of the day we deal with messy human inputs, and the required bookkeeping makes that tedious and inexpressive in Rust.

> because it’s new in the same way Haskell is new to a Java dev

Do you have any hypotheses about why we don't see as much publicity for Haskell then?

Hey nice to see you here, your SO posts have tremendously helped me learn Rust.

I think Haskell is just too abstract for most of us. I love Rust traits and see how it directly came from Haskell but I couldn’t learn Haskell even after like 3 serious tries. Maybe a good portion of the problem is in the documentation and not the language? That said, the extremist purity is simply impractical compared to Rust which gets 90% of the way there without forcing all the architectural dances Haskell does. Just my opinion.

You are quite welcome!

I can't add much to the Haskell part as I've only ever used it sparingly. In many aspects, I view Rust as only having one or two small things that are new (or at least new in a non-research programming language). Its big strength is combining a lot of existing good ideas in a principled manner.

I’d agree, basically Haskell is focused on academic purity and abstract experimentation while Rust is focused on being equally practical and innovative at the same time.

Haskell is actually used by companies to solve practical problems, a non trivial example being Facebook: https://www.youtube.com/watch?v=mlTO510zO78

Not too bad for an abstract experimentation.

Haskell is easier to learn than Rust because it's literally just math. There is no "dropping" variables and no need to side-step the lack of GC, because you never "drop" a variable that you've stopped using in a math proof. You just let the GC deal with all that stuff. And you don't have a "stack" vs. "heap" distinction, instead you work directly in terms of function arguments and the returned values. You have currying so you can work naturally with parameterized and partially-applied functions, just like in math, etc. Lazy evaluation for "infinite" sequences and objects. That kind of stuff.

GC is OK if the only resource your program needs to manage is RAM; and, in particular if time is not among them. There are many such programs, including the favorites of Computer Science, such as compilers.

Add a single other resource, and now you need resource management. Once you have resource management, memory is the easiest thing to plug into it.

If you start out having resource management, you never wonder whether GC would be a good idea. GC turns into a solution desperately looking for a problem, and finding none in your neighborhood.

> Haskell is easier to learn than Rust because it's literally just math.

That explains why it was so hard for me to learn: I'm awful at math. The most advanced math I could understand was high school algebra.

Haskell is great if you would rather be doing maths than solving actual, real-world problems. And, either don't care about performance, or like subverting your design to get it.

There are plenty of such people, and they need something to do that keeps them out of the way of people interested in solving real problems efficiently.

Don't we?

I think I see more posts about Haskell than Rust here on HN. (What makes sense, since fits a larger set of applications.)

Were you there when Haskell was new to the mainstream? For a few years there seemed to be nothing else on proggit.

sorry for the tangent, but what has Go turned into in your opinion? (I'd believe it fits quite well your definition)

It seems to have remained pretty much exactly as it arrived.

Rust is great and I'm really glad it exists; however, I'm skeptical that anyone ever "gets up to Python speed" or "gets up to Go speed", at least provided "speed" means "time to an acceptable result" and not "time to perfect" or "time to pacifying rustc". It's a laudable aim, but I don't think we're close. There's still a lot that Rust makes you think about that Python/Go/etc don't, such as memory management and lifetimes. Even if you are very good at thinking about those things, the cost isn't zero.

Of course, Rust gives you a lot in exchange for the reduced velocity--safety and performance; however, those are tradeoffs and we should talk about them as such. It feels dishonest to present Rust as "as productive as Python" even with the "(given enough experience)" caveat.

I feel like these days, provided there’s a library and I’m not writing stuff from scratch, I’m just as fast at Rust as I am with Ruby. I spent way more time debugging Ruby problems and fixing bugs than I pay upfront with Rust.

It really depends on how you measure productivity.

But also, I don’t think that “makes you think about memory” is that simple. I don’t have to think about memory in Rust very often at all: that’s what the compiler is for! When I make a mistake, it corrects me, and I’ve only thought about it for a few moments.

Fully agree about "depends on how you measure"--that's kind of my thesis. If you're willing to trade iteration velocity to gain correctness, I would seriously consider Rust, but probably not if the value proposition was inverted.

> But also, I don’t think that “makes you think about memory” is that simple. I don’t have to think about memory in Rust very often at all: that’s what the compiler is for! When I make a mistake, it corrects me, and I’ve only thought about it for a few moments.

Ok, you don't think about it, but the back-and-forth with the compiler still takes a nonzero amount of time that you don't have to deal with in a GC language. At least not until you start to hit upon GC performance issues, at which point the value proposition shifts in Rust's favor, which ultimately brings me back to my point about it being an issue of tradeoffs and my skepticism about Rust-as-silver-bullet.

> I pay upfront with Rust.

But you do pay up front! That's a big deal if your design is not set in stone (which is not a synonym for "prototyping").

I also think this is not a simple question; Rust’s rules provide critical feedback during that early phase. It’s valuable when getting started too. The prototype phase may last slightly longer, but I end up much closer to the final design with its help.

(Again, as always, YMMV.)

I don't recall seeing the community arguing strongly for re-writes. I see people who want to do rewrites for fun/education. For example, just because they love the language and prefer to work in it. In some cases people make the case for re-writing sensitive libraries in Rust, but I think a) they are not in general arguing confrontationally; b) they tend to have a point technically speaking. The missing piece is whether it makes sense long-term, with different pools of potential contributors etc.

> To me the Rust community seems to want to argue that everything should be rewritten in Rust

I haven't seen this. At most, I've seen the push for rewriting important libraries where security is a core issue in Rust. I don't blame them. I'm tired of C/C++ being used everywhere because of performance, leading to the current-day situation of so much fundamentally unsafe code running the world.

I'm involved in a couple of github projects where we have had drive-by "hey, rewrite your project in Rust" PRs. Obviously not official or anything, but never seen anything like that for any other language.

I feel like those are actually trolls. I don't remember the last time I saw someone serious about rust doing those types of silly stunts.

Oh, back when Java first came out, Sun themselves were pushing this ("Rewrite it in Java!") line in spades. The hype train was unbelievable back then.

There is no such language as C/C++. You and I are tired of C being used where using a more powerful, safer language would also be faster. Rust could be that language, but C++ is another, and much more likely to still be known in ten years.

/ = or

As in C or C++. I didn't mean it as its own language. And C++ has plenty of issues where I'd consider it equally unsafe. Unless you're a god tier programmer, and even then, it's impossible to write safe code without insane amounts of effort that can't be expected in most projects.

OK, I will bite. If I had to come up with a case where Python is better than Rust, I would say with rapid prototyping and scientific computing. If you just want to try a few things out, python has faster development cycle and if you want to do some super clever math python has better library support. With a bit more mind stretching, I can make a case for Go with a bit more mind stretching. If you want to write a massively parallel network server of some sort you might be better off with Go, especially if you want to use protobufs and grpc. But what would be the case for Node and Java?

For massively parallel even with async, I still think Go is better than NodeJS. I still don't know how to do bounded parallelism in NodeJS but really easy in Go.

https://github.com/caolan/async/blob/master/lib/internal/eac... - this is the code the async Node lib uses for every "(X)Limit" function to limit the number run at once.


I don't know about node. But there's whole lot of java code and libraries out there. Otherwise why would people build other languages for the JVM?

Ease of writing; Most of code is okay having a GC. But time to produce working code (not necessarily 100% correct code) is important.

Rust is created for low level stuff. It is wrong to expect web backend programmers to deal with ownership, stack-vs-heap and all.

> It is wrong to expect web backend programmers to deal with ownership, stack-vs-heap and all.

I am a web backend programmer. I respectfully disagree. I would much rather deal with ownerhip and related issues than deal with dynamic typing fallout. Unfortunately, I am stuck in Python land for some foreseeable future.

> But there's whole lot of java code and libraries out there.

That is true about every other popular language. Rust might not have the ecosystem, being a lot younger, but why would anyone pick Java out of all the other options?

As far as I can tell, the only two reasons people continue coding in Java are "We have an existing Java ecosystem, it is easier to continue doing what we have been doing than to switch" and "Java is what we know best and it is easier to use Java than to learn new technology stack".

> I would much rather deal with ownerhip and related issues than deal with dynamic typing fallout.

Those two things aren't connected. You can avoid both of them by using one of the many statically typed languages with a GC. It might be the case that Rust has other advantages over those languages that make power-assisted manual memory management a cost worth bearing, but it is still a cost. The amount of successful web backends written in Python/Ruby shows that performance demands on a typical web app are nowhere near high enough to justify doing away with the GC.

Here's why we use Java:

1. It performs well - we're a small company, so hardware costs matter to us. Its a similar performance class as Go and C# - if you want to go faster, you likely have to use Rust, C, or C++.

2. As said, the ecosystem is huge. If you need to do something, there's probably a library or tool for it. If you have a problem with one of their libs, someone else had the problem too. Unless your business is consulting, spending your time going down paths no one else has gone down just so you can use a shiny new language is a waste of resources.

3. The language isn't full of too many concepts. This makes it easier to get people up to speed with it if they're unfamiliar. I like Rust for some personal projects, but lots of the complexity of the language is completely pointless for most of what we do at my company.

4. The JVM is great.

5. We already know it.

Even ignoring #5, our priority of languages is probably C#/Java, then Go. Java is a meh language. And I feel like the annotation soup only makes it worse: it makes Java both verbose and magical, a truly shitty combination. But the ecosystem is awesome. The performance is good. The JVM is great.

With .NET Core, it might make sense to look at C#. But the language is fairly similar to Java anyways. Switching for switching's sake seems pointless. And Microsoft only relatively recently started officially supporting Linux, so I would be wary of using it for greenfield, much less switching our existing company.

Kotlin is a decent contender here too. But it's not that widespread as a backend language, at least not yet. If I could pick any language, I would choose Clojure because it benefits somewhat from Java's ecosystem and is (IMHO) the best JVM language. Immutability is killer, and I find dynamic typing with specs a good middleground between purely dynamic and purely static languages.

But Clojure makes things pretty difficult when it comes to the hiring end of things and developer familiarity. If I worked at a greenfield company solving the same problems I do today, Java would probably still be my first choice.

> If I had to come up with a case where Python is better than Rust, I would say with rapid prototyping and scientific computing.

Scripting? I'm not gonna write a 50 LOC single-use script in Rust.

I've found that a lot of scripts end up not being single use. In my case they usually do end up rewritten in Rust, with the benefits of having a proper --help command from the bother. Once you know enough Rust the obtuse parts of the language that must exist to cater for the performance critical crowd cease to be a problem.

I do write a lot of Python and Bash scripts, even in my Rust projects. They're perfect for gluing together a build. But I'd add that as soon as I want an external dependency (often a more featureful command line flag parsing library), I usually RIIR.

Can Rust do things like heap compaction? You could do it by hand I guess but its not exactly trivial. There's probably a whole class of problems the GC still excels at.

JVM tooling is also pretty nice. Can you trivially get deep app metrics from any Rust program?

I think you're asking rhetorically, but just in case:

1. Rust-the-language doesn't know anything about allocations, so strictly speaking, it cannot. Furthermore, without a GC, it's unclear how it could in the first place, given that a compaction would invalidate all pointers to that memory.

2. Certainly not to the same degree as the JVM, given that there's nothing inherently to inspect, like there is in languages with a runtime. You can instrument your own application, but that does mean doing the work yourself, and you only get as good of results as you put in in the first place.

> Rust-the-language doesn't know anything about allocations

AIUI, Rust knows more about allocations than it should, since it's still limited to a single global allocator, and Box<> (which relies on that global allocator) is implemented via compiler magic and cannot be supplemented by equivalent library code. If Rust supported "pluggable" allocators in some fashion, fancy features (including heap compaction, although I find that a bit dubious TBH) might become easier to implement.

Global allocator is a standard library concern, not a language concern, and Box is magic in only one tiny way that doesn’t actually have to do with allocation. Eventually that will be available to other libraries too.

> If Rust supported "pluggable" allocators in some fashion

It's coming, but it's still unstable and being actively developed

- https://github.com/rust-lang/rust/issues/32838

`std` data structures that are generic over type of allocator are in the works.

I think that’s ok. It takes a while to figure out where a language is ok and where it’s maybe not ok. Also by doing stuff it may not be perfectly suited for right now there is an incentive for improving things.

I find it comforting that the Rust community is casting a wide net, even if it’s not always the best fit. It’s something I always enjoy about working with Python.

There are some platforms and ecosystems that pour 90% of the effort into a handful of popular niches, but once you leave that comfort zone you’re on your own. Elixir can feel like that; Ruby/Rails too back in the day.

One major reason for the recent explosion is it's first class WASM support, especially since it doesn't need a GC.

It just has language features that make sense for the web, which is a huge sector. (parallelism, memory safety, speed, JS interop)

Rust using the LLVM toolchain is a real plus, which Clang also uses in the C++ world. The Clang and Rust compilers are basically frontends to LLVM, and any language that compiles using LLVM is translated to IR (intermediate representation). All code optimization is done on the IR code itself in LLVM, which both Rust and C++ compile down to before being compiled further into assembly. That means that the same effort that goes into optimization in the C++ world for Clang is shared by the Rust community too, and any other compiler that uses LLVM.

We have started doing our own optimizations too: https://blog.rust-lang.org/inside-rust/2019/12/02/const-prop...

Your overall point is absolutely correct though. We couldn’t have done this without LLVM.

Can you comment on the current state of non-aliased related optimizations? The issue tracker is byzantine on that one and i can't tell if or to what degree those optimizations are now done.

Right now they're disabled, pending patches on the LLVM side. You can keep track here: https://github.com/rust-lang/rust/issues/54878

I don't know the current state, but I hang out in the Zulip room dedicated to the work on the optimizations

- https://rust-lang.zulipchat.com/#narrow/stream/189540-t-comp...

Yes, Rust has the potential to be faster than C, or even C++. But the compilers' implementations of such optimizations are far too buggy to turn on.

All the usual caveats apply, but benchmark game has rusts median already better than c++, but not as good as c. They are all so close that performance shouldn't really be a consideration between them I think. You can see g++ vs clang++ now too.

They’re not on right now.

This is a broad over-simplification of compiler engineering. LLVM IR is a very leaky abstraction, and there are plenty of optimization passes which make sense for one but not the other. Plenty of optimization passes can and do assume that the LLVM IR is "roughly clang-shaped".

This is the reason that (last I checked) Rust (by default) runs LLVM optimization passes in the same order and quantity as Clang, and even seeks to have the frontend produce LLVM IR that resembles what Clang would produce.

However, modulo LLVM bugs, the worst to be expected from a frontend selecting a different set or order of LLVM passes would be a loss of codegen quality, which may not be particularly crucial for non-C++-shaped languages.

The other nice part of using LLVM is that you don't have to write a new Rust compiler for a new target, you just need to write the LLVM backend to convert LLVM IR to the target's assembly. That's substantially easier to do. So while LLVM doesn't support as many architectures as GCC yet it's far easier to add new architectures to it.

The example of an error message in the blog post is the kind of thing that makes me seriously consider trying out rust. It's excellent. Are most rust error messages like that?

In my experience, the vast majority are exactly like the error they show. Some are even better. I haven't hit a warning in ages that hasn't been able to be auto fixed by `cargo fix`.

However not all of them are. Back in the pre-async/await days you'd end up with some really gnarly implicit types in some really big functions with lots of returns. Then sometimes you'd make a mistake on one of the returns and the compiler would assume that your mistaken type was the right one & point out all the places where the actually correct type was returned. Then you'd have to go hunt for where you needed to add a `as Box<Future<Item = _, Error = _>>` to get it to compile again.

I haven't hit any issues like that since I started converting the gnarly stuff to infinitely simplier async/await code, but I have to imagine those kinds of issues are still lurking in other areas where you can't get away from complicated code.

Even with that I whole-heartedly recommend anyone that's thinking about it just go try it out and/or read some of the book. It's a delightful language to work with. I have way more fun working with Rust than I have with any other language. It takes care of so much of the BS that I don't want to have to think about, so I can just think about the interesting stuff.

Thanks for the kind words. I would say that subpar errors fall in one of two camps: incredibly uncommon (so we haven't "exercised" that muscle to clean them up) or incredibly hard to deal with. I monitor the issue tracker so if you do encounter a confusing error, file a ticket, we treat them seriously.

Thank you for your hard work on rust. The intelligent error messages are a significant part of what makes rust such a joy to use.

And will do, if I encounter them.

I'm one of the people working on UX and ergonomics. I would say that we aim even higher than what that output in particular shows. If an error could possibly be confusing to people, it gets reworked.

Years past we spent a lot of time honing general common errors to a pretty neat level, then we moved on to detecting specific cases. I would say that the quality of the output is a bimodal distribution with a cluster of really high quality for common errors, and a big but shrinking cluster of confusing errors for more advanced features.

To give an example, async await relies on three things: syntactic sugar (which means there's generated code that's not in the user written code), associated types (that had badly confusing type errors) and impl Trait (that had confusing type errors). The later two features didn't receive much love for a while because they were advanced features that a newcomer would be unlikely to hit, with exceptions for crates doing interesting but confusing things with them to provide a nicer API. But when the dust started to settle aroune async/await it was clear to me that people would be seeing the stabilization announcement, consider trying rust and jump straight to very arcane errors that would now be very easy to hit. This made me and a few others actually spend the time to drastically (if not entirely) improve those errors ahead of async/await stabilization, with the nice side effect that those features are also up to the level of quality that we want for newcomers. The syntactic sugar part also plays a part on how you explain succinctly and clearly that the type or inference error you're seeing comes from a return type materialized out if the aether, but I think we've gotten good at that.

If you will be picking up Rust to try it out, I encourage people to use nightly, not because of features but rather because we have diagnostics improvements daily and they can be the difference between having to read the book to understand how to fix your issue and just following the compiler's lead. As an example, you can see this recently landed PR: https://github.com/rust-lang/rust/pull/68267

I really appreciate that people are thinking about language ergonomics in a serious way.

I've recently been using Flutter and it's a delight to get an error message like "you did X, but Y was uninitialized, so you need to put a call to Y.Z in your code first". When my problem is some conceptual mistake, a traditional error message, like "null pointer error in Y" just confuses me, because I don't even know what Y relates to what I'm doing.

I love that you and others are taking the time to see what really went wrong. Partly because it solves my immediate problem, but also because I know that's exerting backpressure on confusing language and library features, which I hope will drive more platform improvements down the road.

Most of them are, yes. Some of them are not. We treat bad error messages as bugs, and track them, and have a few dedicated contributors working to make them better all the time.

Worth noting that Rust tries to set a high bar for error messages, so not just bad, but even pretty-okay-but-could-be-better error messages also get tracked as bugs. As a result, 1/6th of all open bugs in the Rust issue tracker are "diagnostics" (i.e. error messages) bugs, making it the single largest category (AFAIK): https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Ais...

Yeah pretty much. A lot of effort goes into trying to make error messages as clear and useful as possible. Also `rustc --explain` can give you more general details about the class of error and there's a website that does the same. E.g. for error E0502 mentioned in the article: https://doc.rust-lang.org/error-index.html#E0502.

It's still possible to hit some edge cases where error messages aren't as helpful as they could be. But these are considered bugs and so will hopefully be fixed.

Most are that good, or better. I actually debated putting that error because it's one that doesn't have a "help:" line that actively suggests how to fix it.

Some errors are admittedly worse, and people like estebank are actively working on improving them.

You're the author of the blog post? Dunno if this is something you care about, but with JS turned off the code boxes are omitted (with no placeholders or other clues that something is missing.)

I am! It's something I care about, but not sure if there's something I can do about it. The code blocks are powered by a `<script>` tag from GitHub's Gists. Unfortunately, I don't have the ability to edit that post without Wordpress completely removing those tags (I don't have appropriate permissions). I can ask for them to put `<noscript>` tags, but don't know if that will really help.

FWIW, I think it was a good choice to showcase the underlying feature as opposed to showing off the diagnostics :)

Yep, I think the only error messages I've seen that weren't easy to read are the old Futures error messages that could easily have type signatures multi-lines long, and some macro errors that say something like "this macro generated an error outside this crate". Even without something like a language server or full-fledged IDE, you can do "error driven development" where the compiler tells you what line has an error, and gives you a suggestion on how to fix it.

The more pressing question: What is Rust and why is it so popular on HN?

I did an internet search for Rust jobs and it was near-zero. Would be nice but reality calls.

Rust is over the "100% hobbyist" phase, but it isn't still in the phase where you hire "Rust developers" verbatim. There's an important phase in between: Rust is being introduced in organizations as we speak, and some people that were originally hired for some other skills, develop in Rust they picked up because they were enthusiastic about it.

I am in that position at the moment. We are a multi-language shop, and there's some components that make sense to write in Rust.

I'm in the same spot. Given the large number of companies who are willing to state that they use Rust (https://www.rust-lang.org/production/users) without being able to find openings that are explicitly for Rust, I'd say you're right.

I just saw my first local, non-blockchain Rust opportunity, but sadly had to pass on it due to other obligations. Everyone I know writing Rust these days is introducing it to their orgs - not waiting for an open position.

That's how I got Koltin going at my job before it was official with Google.

Not everything has to be about employability. You can still write code to scratch a personal itch, or for the pleasure of the craft.

But actually a lot of the big tech companies are using rust, they’re simply not advertising jobs.

You don't look for Rust jobs. You rewrite your current job in Rust. :D

it's like 8 pages just for SV on indeed

Weird, I did a search and I found 13,000 jobs mentioning Rust on Linkedin.

It's kind of how like when Go first bust out on the scene and every org that was "doing DevOps" claimed they had "Go in the building", the reality is you wrote CLI scripts and did 90% of your job in Java or Python. They may mention Rust, but doubt it's what you'll be solving the majority of business problems in.

I didn't a search in Indeed and found jobs like:

- machinist

- maintenance worker

- crater/packer

- painter

I wish there was a better name, still better than go, although they successfully adopted golang so now it is easier.

Can't edit now, but of course "didn't" supposed to be "did".

At Commure we use Rust everywhere, from our backends to our cli tools. Any shell script longer than a few lines becomes a binary. The only place we don't use Rust is in the frontend, where we use JavaScript and TypeScript.

People like to believe that the biggest problem they have with their code is memory safety, a problem Rust puts a significant effort into solving. At this point, most uses of Rust are also entirely academic, which appeals to HNs because they prefer theory to reality because reality is messy.

> At this point, most uses of Rust are also entirely academic

At this point, this is not true. There are significant production deployments of Rust. Heck, Rust code helped me post this comment, and read yours! (Okay that's strictly not true because I have Chrome on this computer, but had I posted from my phone, or from my other computer, it would have been Firefox.)

I don't think it's fair to say that Rust is entirely academic. It has a lot of production users including some very large names: https://www.rust-lang.org/production/users

I didn't say that Rust was entirely academic, I said most uses of Rust were academic.

You have any stats to back this up?

Wow, that is an extremely well-written brief introduction to Rust. I love the way it manages to address some more technical (e.g. FFIs, distinction between borrow-checker and other parts of compiler) but important concepts despite being so short. Thanks very much Jake Goulding if you're reading.

You are quite welcome! Hope to see you writing some Rust sometime!

I have tried one project so far: https://github.com/dandavison/delta

Rust for me is the modern C/C++, as much as Go is the modern Java. I see no point going back to C/C++ now and I will now reject any job offers that deal with these languages.

I like the fact that Rust has a set of libraries (crates and the standard library) that provide a lot of the features that you end up re-inventing if you stick with C. Even C++ is pretty fractured in this regard.

A lot of why this is hard in C/C++ is memory management. Even if you had a package manager it would be hard to compose libraries together unless they were designed together (like boost for C++).

I see that you have no experience with C++ in the past decade. There has been no fragmentation in C++ resource management since C++11.

That's fair - last time i used C++ in earnest was around 2007. Unless they broke compatibility, it would still be opt-in, though, right? Nice thing about Rust is that the resource management approach is built-in and enforced by default.

Everything in C++ is opt-in.

The Standard C++ Library supports user-managed allocators for all the containers, heavily used in embedded, low-latency, and real-time applications to get deterministic performance.

Lack of standard support for user-provided allocators indicates immaturity. E.g., C++ lacked them until 2011.

I realize /r/rust (Reddit) isn't representative of the entire Rust community but it's given me a really bad impression of Rust culture.

Reddit is great for memes and humour, not much more. Go through any subreddit on a topic that you know well, and you'll likely be disappointed.

/r/haskell is pretty good. /r/python isn't great, but not bad either.

There are subredits of every kind, even great ones. But they change with time.

As an embedded systems engineer I have very mixed feelings about Rust. There are a lot of things to like, but Rust seems to miss the point why C++ didn't replace C and will fail at that for the same reasons. I wish for an economic, unexciting, conservative evolution of C, which I don't see in Rust. I could imagine C++ being replaced by Rust, though I don't think borrow checking is the future of programming.

Another point is the tight integration with cargo, which may lead to the same dependency problems that npm has. But it will cause significantly more struggles because of licensing issues. While most npm code was running on servers, it didn't matter. In the embedded space companies typically insist to have every library checked by a lawyer before it gets shipped with the product, which will make cargo essentially useless.

The last one is the community. In fact I think a programming language is to the largest part about the people using it. And Mozilla sadly created a hype and a hostile community by aggressively evangelizing the language.

Just so you know, there's tools that let you check the entire set of licenses of your dependency tree, and whitelist/blacklist them. Amazon implemented one after they started using Rust more seriously.

> I wish for an economic, unexciting, conservative evolution of C

That's not a bad description of Cyclone, Rust's direct predecessor. It went nowhere because it was so "conservative" over C as to be deeply unintuitive, and it lacked features that matter to modern programming. Rust is nonetheless far less complex than C++, and that in itself makes it a plausible C replacement.

The reason that it's popular is that it's immediately clear that Rust's model of memory safety without a GC and safe concurrency is the best way to create a programming language since it unifies the memory safety of GC languages like Java, the efficiency of C and the concurrency of message-passing systems like Erlang in a single language that has none of the drawbacks of those systems.

Before Rust, everyone simply assumed that it was impossible to create such a programming language since it would have otherwise been what everyone used, and now that it turns out that it's possible, it's clear that it's the best solution and what should be used in the future whenever possible.

Still not hyped. The article does not show anything special or new about the language that would attract me personally. Type inference -- nothing new and exists in many other languages. Actually how about compile type inference not only in function bodies? :) Functional niceness with iterators -- also nothing new. It can be even more succinct and elegant in Scala for example. But Scala is not as fast you'd say! Yeah, so what? Python is not as fast as Scala, so.

Control over low-level details is something that exists and should be in any system-programming language. How is that even a benefit? It is a niche feature.

Memory safety? You can circumvent it by using "unsafe" and as recent Actix case shows it can propagate really deep. Should I read the code of any other Rust library now? What if I am a programmer newbie driven by the hype without a clue what does memory safety entail? What-ifs... I won't talk about compile times and the fact that in order to compile some cli tool one has to download ~200mb of rust "stuff". This is simply insane and I refuse to understand how is this considered to be not an issue.

Rust ecosystem is probably its strongest point right now which is somewhat funny because it grew out of beliefs in the above "benefits". So, not hyped, sorry.

Haven't used Rust, but I don't think your argument makes any sense.

Isn't the point the combination of features is unique?

It seems like if I invented a functional sledge hammer that only weighed 1oz, you'd say:

> It can hammer big nails? So can other sledge hammers!

> It only weighs 1oz? So does a plastic toy hammer!

> So I don't care.

> Actually how about compile type inference not only in function bodies?

This is actually an explicit design decision; it means that the analysis is tractable, and that you don't get spooky-at-a-distance error messages.

It's a major detractor, especially for people new to Rust.

The number of times I see people recommend "just cut and paste in whatever type the compiler said it expected ..." just makes my hair curl.

It also tends to make the code more obscure and unreadable, sometimes completely so.

Hmm, I see. It makes sense.

"It is a niche feature" looking at C and C++ usage that niche is pretty huge.

It is, and C/C++ are used in so many areas which are not system programming right? Being a scientific Python backbone is one of them for example. My claim was that it is nothing out-of-ordinary. In fact, I really dislike the article's somewhat evangelist attempt to target newbies. These so-called benefits existed and do exist in so many other languages. The only thing that Rust comes with is memory safety which on closer look is actually an illusion and is a pretty evil one. I would praise Rust for speed, yes. For ecosystem, yes. But that's it.

"My claim was that it is nothing out-of-ordinary". Well I guess will agree to disagree there are pretty prominent cases of very capable people trying to do a project in C++ and failing and then leveraging Rust and actually delivering.

And it would be great to read about such projects. But I have not heard about such. Maybe I would change my opinion.

Mozilla namely: "By 2017, Mozilla had made two previous attempts to parallelize the style system using C++. Both had failed." but they were able to complete it in Rust.

I would be really surprised if they failed to do it with the language they invented.

They is not exactly same set of people

What influential applications are written in rust? For c++, there is llvm, chrome, game engines, I feel like c++ is standing very strong in any of these fields still, why is that? Do u think it’s going to change soon?

No essential programs are in Rust, in the way that e.g. Docker is in Go, or your examples in C++, and none are on the horizon unless Cargo becomes a popular way to build C++ or C programs. Rust is popular to post about on HN, but the number of people actively coding it is at least 4 orders of magnitude fewer than mature languages, and the number of people adopting it, likewise: the number of people adopting C++ is many times larger than the number who have ever even heard that Rust exists. Those numbers will take many years to change, if they do. Just as likely, some new hotness will pop up and distract the early adopters; Rust could very possibly fizzle out. (That would be a shame unless the new hotness were enough better. Rust++?)

Promoting Cargo as a way to build C++ and C programs could be a way to establish Rust underpinnings. Cargo is better than most other build systems now used for C++, and with C++20 getting modules, the fit is improving.

Well, I would guess FireFox, sort of. If I recall correctly Rust was created to rewrite FireFox and make it better.

The Oxidation page [1] seems to give an overview where it is.

[1]: https://wiki.mozilla.org/Oxidation

Such momentum is not so easily overcome. The roots of Chrome's codebase and LLVM are both significantly older than the very beginning of the Rust project, for example.

If Rust manages to actually supplant C or C++ it would very likely require decades and generational change.

Does anyone know how StackOverflow measures "love" towards a language?

> % of developers who are developing with the language or technology and have expressed interest in continuing to develop with it


I like everything I see and read about rust but I'm unsure where I'd fit it into my work. Does rust have a future in areas like backend web development or mobile?

My employer, Cloudflare, uses Rust as part of our mobile app for It’s still rough around the edges, you basically integrate Rust like you would a C dependency, but it’s been working great.

There are some backend web development deployments at other companies, but the ecosystem has been changing a lot over the last year. It’s starting to settle down though. Expect more “Flask” and less “Rails.”

it's pretty great for non trivial CLIs. I was using it at my previous org for a tool to take JSON config files to generate a bunch of C++ boilerplate so we could rapidly prototype different ideas.

I like Rust, however as usual the article fails short of mentioning Ada, and GC languages that share the same resource management capabilities as C++, alongside their GC.

I wouldn't want to mention any language I don't have experience with for the risk of mis-speaking. I also tried to minimize talking about any specific language where I could.

Fair enough.

I just made the point, because from security point of view, we all have to gain no matter what safe systems programming languages get adopted.

It doesn't need to be Rust vs the others, in what concerns improving the current state of IT security.

For example, Nvidia is now adopting Ada/SPARK for security critical firmware.

Rust newbie here. How do you fix the compile error for the example given? I imagine it has something to do with transferring ownership, but I’m not too sure.

Are you familiar with C++? That example is roughly equivalent to:

  #include <string>
  #include <iostream>
  #include <string_view>
  int main()
      std::string name { "Vivian" };
      auto nickname = std::string_view { name }.substr(0, 3);
      std::cout << "Hello there, " << nickname << "!\n";
which will happily compile, but whose behavior is undefined.

Is the behavior undefined because std::string makes a deep copy of the string? I thought 'Vivian' would be placed in read-only memory and as long as you don't modify it, you can hold read-only references to it.

Yes, `std::string` owns its own copy of the string in typical implementations (as does Rust's `String` type).

`std::string_view` references that copy. `std::string::clear` destroys it, leaving the `std::string_view` dangling.

The example won't compile because nickname is just a reference to the first three bytes of name, but then name is cleared, so nickname would be a bad reference. That are two ways to go around this:

1. Print the nickname before clearing the name so that nickname is still valid when you print it (swap lines 4 and 5).

2. Make nickname a copy of the first three bytes of name, rather then a reference to the first three bytes of name.

    let nickname = String::from(&name[..3]);

The nickname works like alias that only shows 3 characters of the name. Before using nickname the code frees the name making both name and nickname invalid. The error here is use after free and one strengths of rust is to detect errors like this.

In C such code would compile, what's worse, it would work and behave correctly most of the time. If your code was more complex (for example using threads) you would get a bug that the code would work fine most of the time, but once in a while it would display garbage.

Lots of these things that look like syntax problems are in fact design problems surfaced by the compiler.

The `nickname` variable holds onto a reference to the substring of `name`. Subsequently `name` is modified (cleared).

This forces you to think about the behaviour. Should the nickname remain constant even if the backing `name` string changes? Probably yes, so you'd take a copy at that point.

Transpose the print and clear statements.

The easiest fix is to clone the String, then build a slice from the copy.

Applications are open for YC Summer 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact