Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

your final assertion implies that any new language that is a significant paradigm shift from c++ must be flawed.


I do qualify that I speak about languages that are still "Algol-derived".

Rust is not some significant paradigm shift (like e.g. Scheme vs C vs Prolog vs Haskell, etc).

It's the same concepts and programming styles as C, C++ etc, plus fighting the borrow checker.


Actually, a lot of the issues that C/C++ programmers have when they are new to Rust seem to be precisely because idiomatic Rust code (which can help to avoid borrow checker issues) is often in a more functional Scheme/OCaml style.

Rust is both algol-derived, and ocaml-derived. And arguably the borrow checker creates a new paradigm entirely.


>The borrow checker creates a new paradigm entirely

I don't think this can be emphasized enough. You can get deceivingly far in rust with an OOP style, only to come to the disheartening conclusion that it's impossible to do what you want with the architecture you spent months of work setting up.

For example, how would you architect a simple single threaded emulator? The CPU is an object, RAM is an object, easy enough. Okay, the CPU needs mutable access to RAM at all times, so we'll make the CPU own the RAM, sure why not? Okay now we want to implement a graphics device that can mutably access RAM, so we just...put the ram out on it's own and make it a Rc<RefCell<T>>?!? Now it takes three lines of code to unwrap all the smart pointers to write a single byte of memory?!? And it's slower because we have to pay for runtime borrow checking!

I went down exactly this road. I still use rust and love many things about it, but I've come to the conclusion that writing typical single threaded object oriented code in rust only looks like it works; it's an awful idea in practice.

I think the reason C++ people have so much trouble with rust is the syntax makes it easy to do the things you've always done, but the mysterious borrowchecker tells you no later on.


It is hard to think about program architecture. Most languages don't make you think about it at all, they just let you jam code together however you want and give you the tools to make it work.

That was the biggest shock I had moving to Rust: I couldn't just do what I wanted, I had to figure out how to do what Rust wanted. But I also wanted to learn how to design systems better, so the fact that Rust makes me think deeper about it is an advantage for me. In an OO language, I'd just lazily cobble things together. The code would work, but I would learn nothing.

And some people would rather do things that way. It is very hard to break habits, and Rust basically forces you to do that.


It's hard to implement unsafe patterns in safe language. It's hard like using ASM with Java, because Java is platform independent language, while ASM is platform dependent language. This impedance mismatch causes problems, which can solved by wrappers.

If we are talking about emulator, why not just make clear communication between CPU, RAM, and graphic device? Memory can be split into rows (e.g. by split_at()), so graphic device can take ownership of a single scan line at a time, leaving majority of the memory unlocked. We cannot avoid problem, but we can make scale of the problem much smaller by splitting memory into pages, so CPU can take ownership of pages, it works with right now, while graphical device can work with it own pages.


I can't understand how using split_at() would work...if the CPU and the GPU both have a reference to the RAM, we're still using an Rc<RefCell<>>. If the slice gets passed into the CPU and GPU's run() functions, then how does this magical memory manager know what to pass ahead of time?

>It's hard to implement unsafe patterns in safe language.

I agree with this 100%. And I think that for certain problem domains, rust provides more safety than you actually want.


Split memory into pages. Then create two types: OwnedMem, and SharedMem. OwnedMem will own page(s), so access to memory will require no Arc. SharedMem will implement safe protocol to access memory from different threads using Arc or atomic operations. SharedMem must also implement .clone(), so both CPU and GPU will be able to hold it.

> And I think that for certain problem domains, rust provides more safety than you actually want.

If writing of unsafe Rust by hands is hard for you, then write code in plain C, then convert it into unsafe Rust using crust.


Just define your memory as `Rc<[Cell<u8>]>` (or something wider, depending on architecture) and you're fine, right?


>Actually, a lot of the issues that C/C++ programmers have when they are new to Rust seem to be precisely because idiomatic Rust code (which can help to avoid borrow checker issues) is often in a more functional Scheme/OCaml style.

Well, those are not the issues that concern me, or that most (in blogs/HN posts/comments/etc I've read) consider the hard parts. It's the borrow checker.


Right. But if you use a data-oriented FP approach, then you will often avoid borrow checker issues entirely. It is people trying to apply OOP patterns with lots of mutable state that constantly run into borrow checker issues.

The borrow checker might seem like the problem, but the solution is to learn to code in a new style.


You can easily implement borrowing in C++ classes.

I worked on a large C++ code base (some 15 years ago, before Rust existed) which did this kind of thing: it had references enforcing single ownership that was handed on assignment or passing.

Borrowing was of course done in the usual way, by passing down references (most often const ones).


Rust has lambdas, ADTs, pattern-matching and typeclasses(although not as powerful without kinds). These things alone makes a significant paradigm shift than programming in algol style languages. You can just use ARC<T> for every heap-allocated value and rust will still offer a significant advantage compared to C/C++.


C++20 has all those things as well, except for pattern-matching expected to arrive by C++23. :)

So if it wasn't for the copy-paste compatibility with unsafe C code, there is already quite a few modern features available in the language.


s/fighting the borrow checker/enforcing rules of data ownership/


i think the borrow checker may indeed be a rather large paradigm shift, and im super interested to know if you can get used to it and be as productive as you are in c++ or if it is innately harder. to me it is still hard to work woth but i habe 30 years of being ised to C or garbage collection


As someone from a JS background, I am far more productive in Rust than C++. C++ makes it really easy to accidentally break something that then takes ages to debug. And using libraries is a massive pain.

However, if you have already learnt to be productive in C++, then I suspect Rust would end up being slightly slower to write the initial code, but not much. And it'd make up for it in ease of refactoring.




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

Search: