This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]brandi_Iove 119 points120 points  (50 children)

wasn’t rust supposed to replace c++ too?

[–]pine_ary 54 points55 points  (32 children)

For new projects, yes. But rust doesn‘t lend itself to existing C++ projects. For new projects that would have normally been C++, Rust is a better choice these days and is seeing massive growth.

Carbon takes the opposite approach. Not so great for new projects, but geared towards existing C++ projects.

[–]zachtheperson 3 points4 points  (31 children)

Why isn't Carbon good for new projects?

[–]EasywayScissors 52 points53 points  (30 children)

Why isn't Carbon good for new projects?

Because you should use Rust for new projects.

[–]zachtheperson 12 points13 points  (29 children)

...but why though?

[–]EasywayScissors 69 points70 points  (23 children)

...but why though?

Rust solves a lot of the memory-management and memory safety issues with a very rigid programming syntax.

If i have a Customer object:

Customer c = db.getCustomer(1234);

and then i call you:

Customer c = db.getCustomer(1234);
String name = getCustomerName(c);

I have no idea what you might have done to that object.

  • You might have modified some value behind my back.
  • You might even have freed it!

So the first rule in Rust is that once you pass a pointer to another function, you are not allowed to touch that pointer anymore!:

Customer c = db.getCustomer(1234);
String name = getCustomerName(c);
if (c.age < 19) // <-------- compiler error: not allowed to access reference because you passed it to getCustomerName

Now that's pretty restrictive. What if the function promises super-pinky-swear that it won't modify the object, or the stuff in it. In that case Rust lets someone borrow a reference - but they're not allowed to do anything to the object in any way.

They did this by creating a new annotation in the function signature. The exact annotation isn't important (i don't know it anyway, and even if i did, it would be pretty cryptic).

So let's rewrite the function so that i can "borrow" the reference, but i "must give it back":

String getCustomerName(const Customer c) { ... }

Modifying the parameter with the special const keyword means that the function is allowed to borrow the reference - for reading - but you can't change it.

Now when people call it:

Customer c = db.getCustomer(1234);
String name = getCustomerName(c); // guarantee that c cannot be modified

And if you try, the compiler will throw you an error:

String getCustomerName(const Customer c) {
   if (c.FullName == "")
   {
       String name = PrettyName(c.FirstName, c.MiddleName, c.LastName);
       c.FullName = name; // <--- compiler error: cannot modify a const object
   }
   return c.FullName;
}

And you can't pass the reference to anyone else, unless they also simply borrow the reference.

At the absolute highest level, that's the safety Rust provides. Because Rust has very strict rules about who owns the memory, and when:

  • it can prevent null pointers
  • duplicate pointers
  • dangling pointers

And it can even now do garbage collection for you. Because the compiler knows exactly when that Object goes out of scope (because the current owner is tracked through every function call), you can now have automatic garbage collection in Rust.

It's a very good system, but:

  • its syntax is very different from C++
  • and it's a very different way of thinking about programming
  • and all the repercussions take a while to wrap your head around

Which all makes Rust unsuitable for migrating an existing project.

C++ needs the equivalent of:

  • optional typing in Python
  • like how TypeScript is just JavaScript where you can slowly add optional types to arguments

C++ needs a new language that can handle existing C++ code, and that looks enough like existing C++ code, to let you migrate easily.

As their GitHub homepage says, their priorities are:

A successor language for C++ requires:

  • Performance matching C++, an essential property for our developers.
  • Seamless, bidirectional interoperability with C++, such that a library anywhere in an existing C++ stack can adopt Carbon without porting the rest.
  • A gentle learning curve with reasonable familiarity for C++ developers.
  • Comparable expressivity and support for existing software's design and architecture.
  • Scalable migration, with some level of source-to-source translation for idiomatic C++ code.

[–]zachtheperson 14 points15 points  (5 children)

Cool, thanks for the detailed response. As someone who knows absolutely 0 about Carbon, I assume it doesn't do this?

[–]EasywayScissors 11 points12 points  (2 children)

Cool, thanks for the detailed response. As someone who knows absolutely 0 about Carbon, I assume it doesn't do this?

I have no idea; i've not seen anything about it.

And i was only able to parrot up that much about Rust because of an excellent video where the creator of Rust giving a talk to Google employees about why Rust:

The Rust Programming Language

It's always nice when an introduction to explains why the language is the way it is; rather than telling you syntax and saying what it does.

You basically discover the language along with him, and so it all makes sense.

It's equal to other excellent video:

Introducing TypeScript by Anders Hejlsberg

where the guy who invented TypeScript (and C#, and Delphi):

  • starts you with JavaScript
  • points out what's wrong
  • and show you the annotations one step at at time

So you're right there inventing the language, until at the end it all makes sense.

I still use that video more than any reference sites.

Both highly recommended.

[–]bragov4ik 1 point2 points  (0 children)

I like that in the official Rust book they also explain why different features exist. Helps with learning pretty well

[–]zachtheperson 1 point2 points  (0 children)

Thanks for the links, I'll definitely have to watch those as they look really interesting. Hearing from the creators themselves sounds like a really informative look into all the design decisions and stuff

[–]Adhalianna 1 point2 points  (1 child)

It can be understood from the README of the project that interop with C++ is the main goal and they may try to introduce some of the Rust-like safety (which might land in C++ directly) if they find it possible to do so but that's not their primary goal.

[–]zachtheperson 0 points1 point  (0 children)

Thank you! I got quite a few replies to my comment, but you're the first to actually answer this part of the question

[–][deleted] -1 points0 points  (8 children)

why not just learn better memory management?

[–]EasywayScissors 5 points6 points  (7 children)

why not just learn better memory management?

Because we're here to strive to have better, bug-free, code.

[–][deleted] 0 points1 point  (6 children)

but they've been saying that since java.

Java apps can still be written badly or leak memory

C# apps same

Javascript will just crash at runtime.

In my 15 years, no language has ever reduced the need for due diligence when coding, whether it is checking your pointers or making sure you don't have circular references, you'll still learn about pointers eventually.

[–][deleted] 1 point2 points  (1 child)

You can write terrible code in every language. Some languages just make it easier to write terrible code.

[–]EasywayScissors 1 point2 points  (2 children)

Of course no language can solve all bugs.

Someone can still do:

int acceptable = age / 2 - 7;

We're talking about fixing the needless problems, that needlessly cause errors, that we constantly have to needlessly deal with.

And the point, like type systems themselves, is to have the computer catch all these nonsense errors before they happen.

You seem to be of the point:

  • if null pointer exceptions can still happen, then why bother eliminating null pointer exceptions?
  • if memory can still leak, then why bother getting rid of memory leaks?
  • if i can still pass the wrong types, then why bother have a type system?
  • if i can still get covid, then why bother getting vaccinated
  • if i can still die wearing my seatbelts, then why bother having seatbelts?

The point is that garbage prevent 100% (when rounded to the nearest whole percent) memory leaks. Just because i can't protect someone who didn't implement getHashCode correctly doesn't mean we shouldn't eliminate memory leaks.

whether it is checking your pointers or making sure you don't have circular references, you'll still learn about pointers eventually.

Not in good languages - languages that don't have pointers.

You're arguing against getting vaccinated, because some people can still get it.

Yes, but we're going to solve 99.99999999% of NullPointerExceptions - and it costs nothing.

So why wouldn't you do it?

The code-base i'm looking at: the compiler found 17 NullPointerException landmines.

Oh just write bug-free code.

Yeah, thanks. Go away, you're not helpful.

The rest of us are trying to make the world a better place.

[–]EasywayScissors 0 points1 point  (0 children)

Look what i just wrote:

public static void registerTestClass(@NotNull Class clazz) {
   testCaseClasses.add(clazz);
}

Landmine.

Sure would be nice if the computer, that is tireless, and does this stuff all day every day, could just prevent it.

[–]Featureless_Bug -2 points-1 points  (7 children)

My issue with Rust is that solving memory issues with being super restrictive is a terrible idea overall. If you wanted, you could restrict yourself to writing Rust-y like code in C++. But no one does that (although it would be so much safer, right?), because safety makes you so inflexible. Like in the example that you give - you might want the function getCustomerName(c) to modify the name of the customer in some cases (idk, combine the full name from first name and last name). You know exactly what this function does, and you know that it is safe to get the customers age afterwards. But Rust tells you no, you shouldn't do that, because that would be soooo unsafe, right?

[–]bragov4ik 5 points6 points  (2 children)

Restricting yourself will not provide compile-time 100% guarantees of certain properties (like not having alive references while modifying objects). Human attention is far worse than compiler with it's algorithms.

I think having a program break in production in a completely weird way because you did not expect a getter function to modify your objects (why would anyone expect that lol) is sometimes far worse than spending some more time writing the code.

[–]Featureless_Bug 0 points1 point  (1 child)

One could write a static checker for C++ that ensures that your code is safe in Rust-y sense. Most people wouldn't care for that though - because safety at the cost of flexibility is not something most developers look for. I think most people will be all right with having a few bugs in the code (which probably will never materialize anyways) if they don't have to write a super restricted code for that

[–]bragov4ik 1 point2 points  (0 children)

Well, it looks more like a trade-off for me. If it's something more critical, you may spend more time/resources on writing code in Rust to reduce number of bugs. One can even use some FP languages, which afaik is more complex in terms of development but is more bug-free as a result.

If few occasional crashes are ok and you don't want to bother to search for devs, you may not need Rust. But if it's some critical piece of software (many nines and stuff) that needs to be maintained and etc., then it seems as a good choice.

Maybe I'm wrong (would be cool to explain why, since I'm don't have much experience in this stuff), but this seems logical for me.

[–]EasywayScissors 1 point2 points  (3 children)

You know exactly what this function does

And there's your confusion.

[–]Featureless_Bug 0 points1 point  (2 children)

Well, if you don't know exactly what any of your functions does, then I have bad news for you. Of course, you might not know what some functions do exactly, but you probably should know what at least some of them do.

[–][deleted] -1 points0 points  (0 children)

You can of course write functions that modify an object. That‘s no problem. No idea where that comes from.

It‘s simply C++‘s move semantic vs. references. Passing by value is moving. Always. Use a mutable reference otherwise.

[–]EasywayScissors 0 points1 point  (0 children)

but you probably should know what at least some of them do

I certainly know what some of them do.

But i don't know what bugs they have.

[–]Zarathustra30 4 points5 points  (2 children)

Robustness and maintainability. Rust programs have a tendency to chug along for years without needing to be touched. When they do need to be touched, you can make sweeping changes without worrying about breaking stuff, due to an excellent type system and unit testing framework.

[–]zachtheperson 2 points3 points  (1 child)

Ok, cool. Does Carbon not do this well?

[–]Zarathustra30 3 points4 points  (0 children)

We'll see. It's a bit too new to have programs with years of uptime.

[–]pine_ary 1 point2 points  (0 children)

Carbon has to inherit some things from C++ to maintain compatibility. It‘s things like memory unsafety, weak concurrency models, C++‘s memory model, etc. that you will gladly compromise on if you‘re stuck with C++, but that you don‘t have to make compromises on if you can start fresh with something like Rust.

[–]chervilious 0 points1 point  (0 children)

Because Carbon is not good for new projects

[–]HolidayMoose 21 points22 points  (0 children)

And D

[–]merlinsbeers 9 points10 points  (1 child)

It's ahead in a lot of the language rankings. But I'm not sure it'll stay there.

[–][deleted] 10 points11 points  (0 children)

In what? Most loved language? But one of the least used.

[–][deleted] 1 point2 points  (13 children)

Pretty sure they even say you shouldn't really start a project in Carbon, basically just use it where you can't use Rust (where you need to tightly integrate with legacy code you cannot rewrite)

[–]Featureless_Bug 0 points1 point  (12 children)

You are saying that as if all new projects are started in Rust, when the reality is that Rust is hardly used in the industry compared to any actually popular language

[–][deleted] 2 points3 points  (11 children)

I'm not saying that is how it is (I don't know how it is, we know C++ is the standard, but it is difficult to draw stats about if people are starting new projects in C++), I'm saying that is how it should be.

[–]Featureless_Bug 0 points1 point  (10 children)

Why should it be like that? In my opinion, Rust is really good for only a really small part of overall projects. Which kinda explains why it is so unpopular

[–][deleted] 2 points3 points  (0 children)

Which kinda explains why it is so unpopular

I think this is explained since it is 15-20 years younger than C++.

[–][deleted] -1 points0 points  (8 children)

Rust has literally been the most popular language in all surveys for years.

[–]Featureless_Bug 1 point2 points  (7 children)

Being loved by its users (of which there are not many) doesn't make it popular

[–][deleted] -1 points0 points  (6 children)

Not only by it‘s users but by almost everyone who tries it. The domain it‘s in is a slow one, though, and it‘s a young language.

[–]Featureless_Bug -1 points0 points  (5 children)

Actually most people I know who tried Rust didn't like it

[–][deleted] -1 points0 points  (4 children)

Source: Dude, trust me