Live data from Hacker News

Matt Godbolt sold me on Rust by showing me C++

collabora.com

611–620 of 675 posts

Re: Matt Godbolt sold me on Rust by showing me C++

#611
post #530

Earlier quoted context omitted.

> Threads and processes do the same amount of context switching. Yes, therefore real webservers use a limited amount of threads/processes (in the same ballpark as a number of CPU cores). Modern approach is to use green threads which are really cheap to switch, it is like store registers, read registers and jmp. > The main cost is memory. The main cost is scheduling, not switching per se. Preemptive multitasking needs…

> The main cost is scheduling, not switching per se. Preemptive multitasking needs to deal with priorities to not waste time, and algorithms that do it The person I am having a conversation with is advocating for threads instead of processes. How do you think threads work? > Modern approach is to use green threads which are really cheap to switch, it is like store registers, read registers and jmp. That’s certainly t…

> The person I am having a conversation with is advocating for threads instead of processes. How do you think threads work?

I was certainly not, I explicitly said that thread-per-request is as bad as process-per-request. I could even agree that it's the worse of both worlds to some extent - none of the isolation, almost all of the overhead (except if you're using a language with a heavy runtime, like Java, where spawning a new JVM has a huge cost compared to a new thread in an existing JVM).

Modern operating systems provide many mechanisms for doing async IO specifically to prevent the need for spawning and switching between thousands of processes. Linux in particular has invested heavily in this, from select, to poll, to epoll, and now unto io_uring.

OS process schedulers are really a poor tool for doing massively parallel IO. They are a general purpose algorithm that has to keep in mind many possible types of heterogeneous processes, and has no insight into the plausible behaviors of those. For a constrained problem like parallel IO, it's a much better idea to use a purpose-built algorithm and tool. And they have simply not been optimized with this kind of scale in mind, because it's much more important and common use case to run quickly for a small number of processes than it is to scale up to thousands. There's a reason typical ulimit configurations are limited to around 1000 threads/processes per system for all common distros.

Re: Matt Godbolt sold me on Rust by showing me C++

#612
post #297
post #237

Earlier quoted context omitted.

And yet, Rust doesn't sacrifice performance and it has all kinds of those guardrails.

I think it is a bit myth that Rust does not sacrifice performance. If you stick to the safe part Rust usually does not seem to achieve the performance of C/C++ according to what I have seen and read. I agree that the cleaner separation of unsafe and safe parts is an advantage of Rust.

The clean separation between Unsafe and Safe rust is precisely, IMO, one of its biggest advantages (and the reason why it'll be superior to almost anything C++ comes up with).

Re: Matt Godbolt sold me on Rust by showing me C++

#613

Earlier quoted context omitted.

What does inferior mean? Rust is inferior to C++ for my needs. This is just a reflection on we started a large project in C++ before rust existed, and now have millions of lines. Getting Rust to work with our existing C++ is hard enough as to not be worth it. Rewriting in Rust would cost 1 billion dollars. Thus despite all the problems we have with C++ that Rust would solve, rust is inferior. (Rust is working on thei…

I don't think it's a defect of the language that your particular circumstance makes it infeasible to port your project. Having a great C++ interop story would be amazing, but Rust would be decidedly less awesome if it had made concessions in that direction early on. There's a lot of warts here, particularly around the fact that all Rust types are "trivially relocatable" in C++ parlance. At the same time, figuring out…

I didn't say it was a defect. I said it made rust inferior for me. Those are different things. I don't disagree with rust reasons for making that tradeoff - but the tradeoff as a result makes rust useless for now, for me. If it works for you great.

Re: Matt Godbolt sold me on Rust by showing me C++

#614

Earlier quoted context omitted.

I do not want a library to panic though, I want to handle the error myself.

Let's say the library panics because there was an out-of-bounds array access on some internal (to that library) array due to a bug in their code. How will you handle this error yourself, and how is the library supposed to propagate it to you in the first place without unwinding?

Ensure all bounds and invariants are checked, and return Result or a custom error or something. As I said, I do not want a library to panic. It should be up to the user of the library. When I write libraries, I make sure that the users of the library are able to handle the errors themselves. Imagine using some library, but they use assert() or panic() instead of returning an error for you to handle, that would frustrate me.

Re: Matt Godbolt sold me on Rust by showing me C++

#615
> You know what's the most interesting part of this whole article? The thing Rust is very famous for, memory safety, did not feature at all.

I think that's the essential point, really... It'd be hard to argue that the rest of Rust isn't overall "better" than C++, but the compromises made to flexibility and ergonomics to achieve memory safety in Rust are the biggest points of contention for Rust critics.

Re: Matt Godbolt sold me on Rust by showing me C++

#616
post #22
post #15

Earlier quoted context omitted.

Maybe contrarian, but imo the `Result` type, while kind of nice, still suffers from plenty of annoyances, including sometimes not working with the (manpages-approved) `dyn Error`, sometimes having to `into()` weird library errors that don't propagate properly, or worse: `map_err()` them; I mean, at this point, the `anyhow` crate is basically mandatory from an ergonomics standpoint in every Rust project I start. Also,…

? definitely works in closures, but it often takes a little finagling to get working, like specifying the return type of the closure or setting the return type of a collect to a Result >

Mapping a Vec to Result and collecting them into a single Result, E> made me feel like a ninja when I first learned it was supported. I’m a little worried it’s too confusing to read for others, but it works so well.

Combined with futures::try_join_all for async closures and you can use it to do a bunch of failable tasks in parallel too, it’s great.

Re: Matt Godbolt sold me on Rust by showing me C++

#617

Earlier quoted context omitted.

How many rough edges will C++ have in another 30 years?

Who knows. It will likely have more than any other language. Though it will also continue to not get credit for things it got right. There will always remain two types of languages: those that nobody uses and those that everybody complains about.

Could it be that it gets no credit for things it got right because it got barely anything right?

Re: Matt Godbolt sold me on Rust by showing me C++

#618

Earlier quoted context omitted.

I wrote such a type library myself, and it worked great. However we eventually realized it was the wrong answer because you so commonly want to display that thing and nobody wanted to write each widget to have a different api for each other the thousands of different types in my library. The current system is a runtime system which has one type, and you set what the unit system is in the constructor. However it means…

Er... why would you need a different API for this? Why not just convert to unitless at the point where the number flows into the UI? Or better yet, parametrize the UI library so that it can display any unit automatically. It could even pull the metadata (like the string for the unit) from the template, so that e.g. binding a kg value to a label would automatically show as "42 kg" etc.

At the point where you convert to unitless you lose all the benefit of strong types. Which is a trade off maybe you can accept. One part of that trade off that you are adding the ability to convert to unitless and thus making it easy to use unitless where you shouldn't.

there are many different ways to implement unit systems. I know of 3 other attempts someone made on just our project to make units work before we settled on this one. There are trade offs and I don't mean to imply I have presented the correct answer for your problem. Only that because of many other reasons (not stated because of NDA) this is the best compromise for us. Your problem is different and you will need to find your own solution. There are lots of possible answers and each has a set of pros/cons. If your problems are simple than you can find an off the shelf answer, but if you need to do complex things you will need to consider what you really want.

Re: Matt Godbolt sold me on Rust by showing me C++

#619
post #507

Earlier quoted context omitted.

I think embedded is one of the specific buckets. You target the compiler your client uses for their platform. There is very little choice there.

Even then you're probably better off using something safer that transpiles to C.

”Transpiles to c” - how do you generally optimize single line performance hotspots in that case?

Re: Matt Godbolt sold me on Rust by showing me C++

#620
post #357

Earlier quoted context omitted.

Sure, but it is pragmatic in other ways as well :) It takes ADT, but not function currying, and so on.

I don't think currying is that big a deal, it's just syntactic sugar that might or might not make things easier to read, unlike ADTs or closures which are important core concepts. I'd love to have a syntax like { foo(%1, bar) } standing for |x| { foo(x, bar) } though. I'm not aware of any language that has this!

I think currying is an important concept and not sugar at all, as it means each function takes exactly one parameter, i.e. in OCaml foo bar baz is equal to (foo bar) baz. Of course, some other languages can try to emulate the use of currying and the original original idea no longer exists there.

I'm relatively sure there exists such a language you are looking for, but I've forgotten its name :(.

There was a syntax extension pa_holes for OCaml (which you perhaps know, as it is natively currying) that worked like

    (\ foo \1 bar)
and it would become

    fun x -> foo x bar
I'm sure the extension was inspired by some other language.. And the pa syntax extension extension mechanism for OCaml has been replaced by ppx a long time ago already; maybe the new system doesn't enable such succinct extensions.
Post reply on HN