I've only ever used GCed (and largely dynamic) languages up until now (Python, JS and Clojure primarily); C is alien and C++ is frankly terrifying. With all that, I've been having a ball using Rust to solve Project Euler problems, with astonishing speed compared to what I'm used to.
It doesn't quite have all the libs you might want for general development yet, but for the things it's currently equipped for it's a lot of fun, and surprisingly easy. (Up until I find myself in a quagmire of lifetime problems of my own making. Looking forward to the coming lifetimes inference enhancement.) It's a surprisingly reasonable functional programming environment too.
Yes, it is a very powerful language and there can be a lot to it, but it shouldn't "terrify" you.
These days, it's generally quite easy to avoid much of its C heritage (including potential security pitfalls) if using the so-called "modern C++" techniques, but the extra power and flexibility is still there if you do ever need it. There are numerous ways of easily avoiding manual memory (or other resource) management, too. The STL and Boost, among numerous other libraries that are out there, offer lots of convenient, high level functionality. The portability of C++ code is often quite excellent, the language and its standard libraries are quite stable, and there are multiple commercial-grade implementations from numerous vendors/projects. You probably won't find anything else that gives you a high degree of performance along with high level abstractions, while also giving you the peace of mind that your code will still compile just fine years or even decades from now.
While it's certainly possible to to overboard and misuse C++ to a point where it causes serious problems, one of the best things about C++ is that it doesn't force you to do that. You generally don't pay for what you don't use, and it's certainly possible to use a very effective subset of the language much as one might use Java or C#, or even Python and JavaScript.
I'd say that C++ is even easier to use than JavaScript is. C++ is much more sensible in so many ways, and nowhere near as quirky or just outright broken in fundamental ways like JavaScript, while also providing at least some type safety and other compile-time checks.
If you want a stable, portable, safe, well-supported language that offers high level functionality without the performance tradeoffs of other languages, then I think that a modern subset of C++ could very well be exactly what you're looking for.
C++ is not safe in the same sense that Rust is. Without the use of "unsafe", Rust is designed to never segfault or have undefined behavior, ever. Even a modern subset of C++ cannot make the same guarantees (consider iterator invalidation, etc.)
I'll gladly use modern C++ techniques and a bit of care, even if that means only getting say 90% or 95% of the safety that Rust potentially offers offers, if it also means that I can get my code written today, and I can trust that it'll still compile unchanged tomorrow, next week, and probably a decade from now.
I think it's great what Rust could potentially offer software developers. But it's still pretty theoretical at this point. The language and standard libraries aren't sufficiently stable enough for serious, long-term use, currently. I hear we may start to see the beginning of such stability at the end of the year, but until it actually happens, Rust isn't very useful, while C++ is.
> and I can trust that it'll still compile unchanged tomorrow, next week, and probably a decade from now.
Given the practical history of C++ implementations, this may be rather optimistic... Though it does seem to be calming down a bit. Unfortunately, my first real work with C++ was with GCC2.96 (the phantom Redhat version of GCC); scarred me for life :)
Long-term stability is not exactly needed for Project Euler solutions, don't you think?
I think you're overreacting here - somebody barely mentions a language and you immediately start praising said language for features not even needed in this particular person use cases.
I doubt that working on small casual programming puzzles is his only use for programming languages. I read his comment as saying that that's merely all he's used Rust for, so far.
Short-term and long-term stability are needed for just about any serious software application or system. They're useful to have even for short scripts that might be reused later on.
And he said he was "terrified" by C++. I explained why he shouldn't be. I'm not sure why you're getting worked up over that.
> I'm not sure why you're getting worked up over that.
I'm not! And I agree with all your points here. It's just that this is not a thread about C++, but about Rust, and about solving small puzzles with it for that matter. Which makes both original mention of being "terrified by C++" and your explanation a bit off-topic. I won't downvote you or anything, I just wanted to point this out.
The language stability of Rust has already reached somewhere similar to Python 2.0: no core features would be removed, so some syntactic changes can occur before 1.0 but that wouldn't invalidate any effort to learn the language before 1.0. Would you say that Python 2.0 is not very useful because it is constantly changing and some features even get removed (albeit quite slowly)?
Yes, it's a big language, but the complexity is at least justifiable, and generally comprehensible.
C++ gives you immense power and a huge range of functionality to choose from, and some of the complexity arises from this. It has a very long history, which also contributes to the complexity. And it's first and foremost a pragmatic language, which of course brings in some complexity in order to deal with the inherent complexity of reality.
If something is seen as "complex" in C++, there's usually a good, or at least understandable, reason for this. You can usually find technical documents or discussion that justify why things are they way that they are, and the reasoning is usually quite sound. And in many cases, it's possible to safely ignore or just not use large portions of the complexity that C++ offers without facing any sort of a penalty or harm.
It's very different from the complexity that languages like JavaScript or PHP bring. The complexity there is usually unjustifiable, and often due to very rushed work, a lack of understanding and poor design, or a lack of care and consistency. They suffer from serious flaws and complexity that were not justified when introduced, and were subsequently not cleaned up or fixed once recognized. They suffer from harmful complexity, while C++ offers beneficial complexity.
If I were to use a word, personally, it might be "daunting" instead of "terrifying" but I have at least some experience with C and manual memory management. In that regard C isn't alien to me, so my perception is a little different from the op.
I don't think the parent post was trying to say C++ was necessarily bad, but the features of C++ being justifiable or not don't really impact my feeling of it being daunting, or terrifying to learn. I could say, with reasonable certainty, that every part of a space shuttle launch probably has a good reason for being there, but the system taken as a whole is still intimidating. It's that C++ is a huge beast and there's just so much there. I haven't gone hard core at looking into C++, but every time I do people start of by saying you need to pick a sane subset of the language to work with, and they all have different views of what is and isn't sane. Add to that the fact that you can do some potentially scary stuff when you're close to the hardware, and I can see why it would be a bit scary.
In my view, the right way to approach that, if I were really trying to learn the language, would be to just pick a guide and go with the assumptions it makes until the reasoning for those assumptions becomes more clear and I can better pick and choose according to my use case. But it's still an intimidating proposition.
I'm also guessing that something like Javascript is less terrifying because of previous experience with dynamic languages. The kind of foot-shooting you do in javascript (because of accidental global scoping, poor equality semantics, or any number of things) at least make sense in the context of having programmed in a dynamic, managed language previously. C and C++ can be pretty scary when everyone talks about manually managing memory or being close to the metal or saying stuff about 'systems programming', which just sounds like crazy voodoo if you don't have a point of comparison.
I think the things your saying are all true. Just trying to offer my perspective as to why, those things being true, a language can still be scary to approach. fwiw
I often find that you need to read a page-long faq (which is an improvement over reading mailing list flame wars over boost vs raw stl vs library-du-jour) to figure out the "right" way to do anything in C++. Now knowing my way around it reasonably well, it's not an issue for me anymore, but not a newcomer.
It's so easy to do it the wrong way, and there's so many examples of badly written or non-idiomatic C++ code strewn all over the internet that a newbie is bound to fall into that trap. This is the same kind of problem I (used to) see with PHP, that it can be fine if you do it all the "right way" and don't do "stupid stuff" but it takes a while to learn what those are. What happens in reality is they google "how to do x", copy paste the code, and modify. Who cares if it's idiomatic or anything.
I would looooove any insight that you have on making the docs better for people who haven't done systems programming before. If you've ever got the time to type out a few thoughts, my email is in my profile.
Assuming you wrote this, you lost me in the book analogy. Once you wrote "let's ignore programming for a moment" I thought to myself, why am I here? And why are we talking about ownership? How do I set up a tool chain and write hello world?
This doesn't strike me as a 30 minute intro to Rust. More like a quick guide to what sets Rust apart from C. Perhaps my expectations would be different with a different title ("How Rust can benefit you as a working C++ dev")
> Perhaps my expectations would be different with a different title
Hmm yes, I will think about it. Ownership is Rust's most important and unique concept, so an intro to ownership _is_ an intro to Rust. I will think about how to make this more clear.
I had no problem with the book analogy. I've been hovering around the periphery of Rust for a while, waiting until I understood the ownership thing before I move into it more seriously.
Thanks for writing this! I think it was a solid step in the direction of clearly explaining ownership. I know more than I did before and I'm looking forward to reading your next piece on it.
The URL to watch is http://doc.rust-lang.org/guide.html . I'm working on it every day. Two more sections should land tonight, and I'm writing the next one as we speak... don't hesitate to ping me with ways the docs could be better, either on IRC, email, or just opening an issue on the repo and CC'ing me.
The docs are great, and the fact that numerous examples with line-by-line explanations are coupled with higher-level prescriptions makes the docs great. Often documentation is too formal, and this formality makes it difficult to follow.
On the other hand, the writing style is way too "cute". It is legitimately distracting to see all these "Hooray!" and "Wait, whaaaat?" and "Not too shabby! I love eliminating mutable state.". It's unhelpful at absolute best.
Otherwise - thank you very much for this. Your docs are undeniably crucial for the adoption of Rust and they're extremely helpful.
Thanks. Yeah, I specifically have a thing open for it being too much in my own voice. Since this was basically ported wholesale off of my blog, it was better there...
And you'll be happy to hear my contract includes examples for _everything_ in the stdlib, so get ready for more of those!
I wrote this a while back as a blog post, it ended up being the actual intro. I hope to go over it again soon, and make it better. There's nothing super wrong with it, but you can always improve! Feedback welcome.
I gotta say, reading this actually made me really excited about Rust. C++ without the annoying memory management but no GC-overhead sounds like a dream.
Just to temper your enthusiasm, the compiler errors can sometimes be irritating, especially when you want to do something the you are pretty sure will be safe. But on the whole if you work with it the pay-off is well worth the minor annoyances. Having the compiler always check your code for memory safety is a huge win for refactoring - C or C++ code bases get really brittle over time as developers forget what is actually going on. I would also say that the number of errors you encounter over time reduce as you gain an intuition for the rules.
Indeed, I’ve been certain that something that it’s not letting me do is safe, only to realise a bit later that actually it was right in a subtle way.
There are certainly some valid things that the compiler will forbid which you then need to work around instead, but by and large I trust the compiler to be right more than I trust myself.
(Bear in mind, still, that these sorts of arguments of Rust’s superiority in such things are frequently only applicable for comparisons with languages like C++; often they are the sorts of things that a managed language would not have a problem with, though also not infrequently it would lead to things like data race.)
> C or C++ code bases get really brittle over time as developers forget what is actually going on
This is very true. And one of the culprits is a lack of modules, an shortcoming that Rust avoids. A module system for C++ is grossly overdue, and I'm not holding my breath that one will be forthcoming.
Part of the reason that "modules" aren't in C++ yet is that there isn't a precise definition of what modules are or what they should be.
That being said, C++ doesn't have even the bare minimum of what would be considered a module system according to any definition. With a lot of hand waving, one should be able to more or less write:
import std::vector;
...and have the compiler (not the preprocessor!) find the relevant declarations and definitions for std::vector. Probably also important are additional restrictions to give more control over when and how preprocessor macros affect client code.
C++ does not have modules. When people say modules they mean how the files compile, and the current way is #include directives which literally copy-pastes the contents of that file into the includer file. This is horribly horrible for compile times, and has been reviled for basically ever.
Right now the way you use a module in C++ is to tell the compiler to dump a subset of its source-code from that module into each file that uses it. Then you tell the linker to link in the objects from that module later.
This is a pretty ridiculous and highly inefficient way of doing things (Facebook improved compile times by crafting a server just to do the preprocessing for you).
Anecdotally, Rust is the most joyful language to program in for me at the moment. I find that I can express powerful ideas in the type system, with deep confidence that the compiler will catch my mistakes, and a strong mental model of how my program will actually execute. I don't know any other languages that "feel" that way. Perhaps D or Nimrod would, but there's only so much time for new languages...
Out of curiosity I implemented the two examples in C++11.
For the number add I used a unique_ptr (although returning by value would be better in every way).
For the shared state I used async with a lamba that calls transform and returns the modified vector through a future. This doesn't execute in parallel for each for loop though. I think something like Arc can be coded in C++ too - template wrapper that returns a RAII lock whick unlocks on scope end.
I think the only big difference is that some errors in Rust are happening at compile time. In the first case the original buggy code was triggering only a warning in C++.
Right now the extra compile-safety of Rust is IMO not worth giving up the other benefits of C++, especially now that C++11 with some extra static checking and good guidelines can go a long way.
> Right now the extra compile-safety of Rust is IMO not worth giving up the other benefits of C++
I can't speak to everyone's use case, but for ours memory safety is extremely important. C++ is not safe, and we still see tons of memory safety issues, many security-sensitive, in practice, despite using modern C++ for all new code.
Even if safety isn't as important to you, there are other reasons you might be interested in Rust: a module system, pattern matching, a standard library which offers better performance than STL for many tasks, ADTs, concepts, a package manager, etc.
I get the feeling most of these commenters who think the words "modern C++" indicate some kind of near insulation from writing security bugs are, in fact, writing security bugs.
They probably think they aren't, but by definition, we are not smart enough to immediately understand the bugs we write. Otherwise we wouldn't write them.
But hey, it's not like a programmer who overestimates his own skills is a new thing.
All kinds of memory safety issues. Heap use-after-free is very common. You can go to Bugzilla and search for sec-critical to get a list of the ones Mozilla has disclosed.
Box<T> is roughly equivalent to unique_ptr, and you're correct, returning by value would be better. Rust idiom is to use stack allocation and borrowing wherever possible.
> I think the only big difference is that some errors in Rust are happening at compile time.
This is true in these examples, except maybe the enforcement of not using a pointer after you've sent it to a task.
That said, there are other examples, like iterator invalidation, where Rust is completely memory safe, unlike C++. Furthermore, Rust has significantly less undefined behavior and odd edge cases. These are in C++ for good reason, but they're still there.
> with some extra static checking and good guidelines can go a long way.
They can go a long way, and that may be enough for you. Big applications continue to have security issues due to problems that Rust would prevent, though: in the last Pwn2Own, all of Firefox's bugs would not have been possible in Rust, for example.
Thanks for the details. In all honesty I am probably not a target for Rust anyway, I almost never use C++ for systems programming, but rather for (cross-platform) application development. It would seem that neither Rust nor Go serve this area and probably do not intend to do it either.
As someone who has researched using Rust for a cross-platform GUI application and looked at Servo for ideas of how to do so, I think the libraries for the GUI layer are still very immature. Servo is mostly a rendering engine that draws its final product directly to a canvas, which is great for the content area of a browser window, but different than what most GUI applications need. (Definitely interested in being corrected by the far more knowledgeable Servo developers here.)
Having said that, immature libraries are to be expected at this point, and I do think Rust is very well positioned to have really good ones for this use case in the short to medium term.
> the libraries for the GUI layer are still very immature.
This is absolutely true, but that's a different concern than "It would seem that neither Rust nor Go serve this area and probably do not intend to do it either," which is what I'm curious about.
One of the open questions with GUI toolkit stuff is that Rust does not have named parameters, but Qt, for example, uses them heavily.
I've only based my impression on a cursory look on the Rust API docs, so I might be wrong, but I did not find any references to database libraries, UI toolkits, multimedia and so on. I did not know about Servo, so I will have to look into it. Will the cross-platform components from Servo be included in the Rust standard library?
To give you some background about the kind of apps I was referring to - I am right now working on a UI-driven app that will be deployed to Android and on the desktop. I am using C++, Qt and platform code where necessary.
All of those things are being built yet, so we don't have much to link to. There are a few work-in-progress things, for example, the postgres adapter is coming along, and rust-graphics for graphical primitives. As we get closer to release, and as they mature, we'll feature them more.
> Will the cross-platform components from Servo be included in the Rust standard library?
As we already have a package manager, I think Rust will tend to have a smaller standard library, and encourage its use more. We'll see though.
> am right now working on a UI-driven app that will be deployed to Android and on the desktop.
We support Windows, Mac, and Linux as first-class platforms, and every pull request (and additions are all through pull requests) is tested on android. iOS coming soon.
I'm glad you mention Qt. Qt bindings are an absolute necessity before my company (which also makes cross-platform applications) could consider adopting Rust.
Yep, I think we are in complete agreement. My inference from looking at the language and community is that Rust absolutely intends to serve this use case.
This is Hacker News, so I'll explain it to you this way: this is specifically _not_ in depth. Have you ever done sales? The idea is that you need to figure out if your customer wants to buy as quickly as possible, and if they don't, move on. If they do, _then_ you move into the longform stuff. If your customer isn't going to buy, it wastes both you and their time.
The idea of this short introduction is to split you into one of two camps: "I want to know more about Rust," or "ewww." If you're in camp one, heading over to the tutorial or Rust by Example is great!
Wow, is Rust ever changing quickly. I think I read some docs a few months ago and most of this was different. It's gotten better though. All that punctuation for different pointer types was a bit too much. And this way of using mutexes as accessors that unlock automatically when they leave scope is brilliant.
I can't wait for Rust to be "done" (and get some kick-ass HTTP support).
Is the language stable enough to learn yet (given that I won't be really using it immediately)? I've been putting off looking at it because it seemed very much in flux.
For learning I would say it is. The biggest thing at the moment is API changes. But the team is now pushing to put stability attributes on all modules and marking deprecated items as such for a time before their removal (these emit warnings if used).
I would highly recommend using the nightlies from http://rust-lang.org/. A list of the docs can be found here: http://doc.rust-lang.org/index.html Reddit is also good for keeping up to date on news: http://www.reddit.com/r/rust Also, IRC is your friend! Join #rust at irc.mozilla.org, and feel free to ask questions. The community is very friendly and willing to help.
There is a very special fun in learning Rust. It isn't stable in the sense that your code from last week will compile this week. On the other hand, it is currently stable enough that all the major concepts are there and most changes are either syntax or API. So reading up on the changes of last week and some search and replace cover most things. Also, most API changes now are introduced through deprecations. All breaking language changes have an RFC process.
The great thing is to see a language while it is still being shaped. Have something you don't like or something that is incredibly clunky? Get involved! The barrier will never be lower. Backwards compatibility is not a thing yet! If the change makes sense and you can muster the resources for it, there is no one holding you back. Code review for pull requests is also awesome, all of my pull requests were accepted on the second or the third try - but for the better!
On top of that, it is a really interesting language on it's own right with interesting concepts worth learning.
How much cognitive overhead is it to think about ownership all the time once you get used to it ? Coming from a GC-languages background I had a hard time thinking in those terms last time I played with it. I ended up having .clone() littered all over the place :)
I don’t find that I need to think about it often at all. And very often I can get away with thinking about it less than I should, because if I make a mistake, the compiler will pull me up short. ☺
When writing libraries, you will typically need to think about ownership more frequently than when writing applications, but it’s normally not at all problematic.
I find that it's no more mental overhead than it is in C. The nice thing is that the development cycle ends up being faster than C for me because I don't have to spend as much time in front of the debugger.
I like this a lot, the right level to get an idea of what Rust is about.
The last example illustrates that concurrency is complex no matter what language you use - the code ends up reflecting the scaffolding enabling concurrency and the actual work ends up buried inside.
Who is "behind" Rust? A company, consortium, academics, BDFL? http://www.rust-lang.org/ doesn't have an about page. Didn't see answer listed in the FAQ.
Mozilla is behind most of it. The original creator has already left the project, so we don't have a BDFL. There is a core team, mostly of Mozilla employees. Tilde has been contracted to do the package manager, I have been contracted to do documentation. There's a pretty significant community for a language so young, our IRC channel has ~600 people in it.
Mozilla is the big driving force, with a small, dedicated group of developers from Mozilla doing a huge amount of the boring 'grunt work', and also making the hard decisions when it comes to design. The community is a huge driving force though, with lots of great contributions being landed all the time.
As someone fairly new to systems programming, I can still see why you'd want to pick a language like Rust over C. But can someone explain to me the difference between Rust and Erlang? They are both system languages, no? Erlang is much more established. But what are the key differences? And I'd ask, "which should I learn?", but that is generally not a great question...
I apologize for not answering your question in this reply, but people still debate which language features are appropriate for which tasks...
My understanding is that Erlang is still primarily used in the telco industry, as it's name implies. In general Erlang shines in doing most software that would run on a server for long periods of time when interruption is expensive (it includes the ability to hot-patch running processes, for example).
Use of a GC is problematic for soft real-time systems (interestingly enough, it can become useful again in hard-real-time systems but that's too long of a tangent here). In rust you can completely ignore the GC just by choosing to not use it. The ease of getting raw-pointer access in rust also indicates places it could be used (I feel like I could write a bare-metal application in a subset of rust with a lot less work than doing so en Erlang).
It used to be that resources were so constrained that the entire OS would be written in a combination of assembler, and something slightly higher level (most commonly C, other times a reduced set of sine other high-level language). This meant that those languages were system languages. Nowadays, writing all but the kernel and drivers in something much higher level has become feasible, so the term "systems language" has blurred in meaning.
I'd love to hear about how GCs can be useful for hard real-time systems! I was always under the impression that you needed to avoid that kind of stuff, so any links / information you have would be really interesting.
It comes down to the fact that in hard real-time you care about doing things in bounded amounts of time, and in soft real-time you typically want to do things "as fast as possible" and fixed-cost incremental GCs tend to be comparably high fraction of CPU usage versus a good generational stop-the-world collector.
Many hard real-time systems already operate with an excess of CPU power in order to simplify analysis of scheduling. Furthermore you are already bounding things like allocations, and a simple incremental GC that runs on a timer tick can guarantee to run in fixed time if you have bounded allocations per timer-tick.
All of this is somewhat moot though as many hard real-time systems completely eschew dynamic allocations.
Erlang would not really fit the systems level programming model. Erlang runs on a VM the BEAM (Bogdan/Björn's Erlang Abstract Machine). Erlang is primarily design for back-end services to other systems. If you want a multi-node redundant system and need to do message passing to handle state and concurrency then Erlang fits that bill.
A significant one is that Rust has no GC, while Erlang does. This can matter if you're trying to build software that's very sensitive to random pauses, or embedded development.
Another significant one is that Erlang has been used to make some of the most reliable software ever for the past few decades, and Rust is still pre-1.0.
It doesn't quite have all the libs you might want for general development yet, but for the things it's currently equipped for it's a lot of fun, and surprisingly easy. (Up until I find myself in a quagmire of lifetime problems of my own making. Looking forward to the coming lifetimes inference enhancement.) It's a surprisingly reasonable functional programming environment too.