Live data from Hacker News

Rust Is Hard, Or: The Misery of Mainstream Programming

hirrolot.github.io

791–800 of 811 posts

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#791
post #735

Earlier quoted context omitted.

I made the mistake of trying to learn Rust while doing async programming. IMO, when it comes to concurrent, it's a matter of picking your poison: Threaded Rust: No overhead of a GC, but overhead of context switches and multiple stacks. NodeJS: No overhead of context switches and multiple stacks, but the overhead of a highly optimized GC. (And I suspect that the GC can do tricks like run when the process is waiting on…

> No overhead of a GC, but overhead of context switches and multiple stacks. Is it really an overhead if it happens in parallel? You have real parallelism, not only concurrency.

Only if your application can limit the number of threads to the number of physical cores.

IE, of you're doing a web server with a thread or process for each incoming web request, you're blocking and context switching. If you have to have locks, you're also blocking and context switching.

This is why async programming models are common, they move the logic of blocking and context switching into the language and runtime, where the compiler can juggle more concurrent tasks in a single thread. It's just harder to do in Rust because, to oversimplify, things that are in stack memory in a threaded environment are now on the heap. In C#/NodeJS, this difference is transparent, but in Rust it's not.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#792

Earlier quoted context omitted.

> We've found that, while the feature work is a bit slower in Rust than in other languages the company used to use (mostly Python), they tend to require a lot less maintenance down the line (less bugs, easier refactoring), and so it ends up canceling out a bit. Python to Rust is a pretty radical swing from one approach to language design to another. I'd expect you could solve most of the maintenance problems with Pyt…

Well, we have other reasons to chose rust rather than a GC'd language (mostly has to do a lot of FFI, which Rust makes much easier than go or Java). I do agree that, if GC'd language fits the problem space, they tend to be much better.

GC has little to do with FFI though. In C# P/Invoke, you basically just declare a static method as external and specify the library where it lives, and that's that. So far as I know, Java has a similar story these days, no need to write JNI wrappers by hand etc. Go is special not because of GC, but because of its green threads.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#793

Earlier quoted context omitted.

> I can assure you that you cannot access undefined memory regions by doing this in Go. Current implementation of slices and interfaces in Go is not memory safe in presence of data races: https://blog.stalkr.net/2022/01/universal-go-exploit-using-d...

Data races are violations of the memory model; of course any code which produces data races cannot be understood as memory safe?

That's part of what the Rust borrow checker does for you: tracking who owns what and enforcing single ownership makes data races that much harder to cause.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#794

Earlier quoted context omitted.

Well, we have other reasons to chose rust rather than a GC'd language (mostly has to do a lot of FFI, which Rust makes much easier than go or Java). I do agree that, if GC'd language fits the problem space, they tend to be much better.

GC has little to do with FFI though. In C# P/Invoke, you basically just declare a static method as external and specify the library where it lives, and that's that. So far as I know, Java has a similar story these days, no need to write JNI wrappers by hand etc. Go is special not because of GC, but because of its green threads.

GC and FFI do have a lot to do w/ each-other though, because FFI usually introduces unmanaged objects.

When a lot of what you're doing is interacting with low-level platform APIs, you end up having a lot of those unmanaged objects. After a certain point, the upsides of using a GC kind of disappear because you still have a lot of places you have to worry about those objects.

Of course, this can be worked around by providing managed wrappers around those unmanaged object, but at a certain point, it becomes easier to just drop down to an unmanaged but safe language (like Rust) that model the unmanaged resources more accurately. In my experience, it's somewhat easier to provide Safe Rust wrappers around your average Windows API than it is to provide a C# Managed Wrapper around the same.

---

And yes, go is special because it has very smol stacks, so doing any kind of FFI on it is a bad idea.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#795

Earlier quoted context omitted.

I agree; if you use dynamic `Arc`s almost everywhere in your code, what's the point in a systems PL whose essence is in managing static lifetimes? Sometimes people use Rust just because many other languages suck; they are choosing between two evils: tedious programming in Rust or inadequacies of another language. It should not be like this. This is why I think we need a high-level, no-BS version of Rust.

> This is why I think we need a high-level, no-BS version of Rust. F# is probably what you're looking for if you want functional-lite programming with a strong type system, but don't want to deal with the pains caused by static resource management.

F# has some nice things in it: I especially like how it handles multiple return values. But compared to the language it is most clearly decended from, OCaml, it ties you to .NET Core and it lacks an ML-like module system and macros.

If you want to use .NET, F# is a fine choice. But otherwise, and especially in the context of an alternative to Rust, I recommend OCaml.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#796

Earlier quoted context omitted.

GC has little to do with FFI though. In C# P/Invoke, you basically just declare a static method as external and specify the library where it lives, and that's that. So far as I know, Java has a similar story these days, no need to write JNI wrappers by hand etc. Go is special not because of GC, but because of its green threads.

GC and FFI do have a lot to do w/ each-other though, because FFI usually introduces unmanaged objects. When a lot of what you're doing is interacting with low-level platform APIs, you end up having a lot of those unmanaged objects. After a certain point, the upsides of using a GC kind of disappear because you still have a lot of places you have to worry about those objects. Of course, this can be worked around by pro…

Unless your code is strictly glue between those lower-level APIs, GC is still a benefit for the majority of it. And, on the other hand, the lack of it in FFI is, at worst, similar to C... except you still have all the other language features (like, say, null safety or pattern matching) at your disposal.

I'm genuinely curious as to what would make FFI in Rust easier than in C#, assuming an apples-to-apples comparison (i.e. use of "unsafe" and associated features in both cases"). Most complexity in P/Invoke shows up when you try to use it to automatically map data to managed data types; but in modern C#, you might as well just use raw pointers, stackalloc, spans etc.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#797
post #10

I wish there was a Rust-like programming language that was just a little bit higher level than Rust. I like Rust's wide ecosystem with high quality packages, the nice type system, traits, the idea that my code generally runs pretty fast even if I'm being lazy about writing good code, and my code usually working correctly if it compiles. I care about speed and correctness but Rust makes me also care about ownership an…

Lobster's automatic compile time reference counting has exactly this purpose: https://aardappel.github.io/lobster/memory_management.html

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#798
post #10

I wish there was a Rust-like programming language that was just a little bit higher level than Rust. I like Rust's wide ecosystem with high quality packages, the nice type system, traits, the idea that my code generally runs pretty fast even if I'm being lazy about writing good code, and my code usually working correctly if it compiles. I care about speed and correctness but Rust makes me also care about ownership an…

Sounds like OCaml is exactly what you want. Many of Rust's features are even inspired by it.

As well as syntactic constructs.

For example, Rust's unusual 'a syntax for lifetime parameters is Ocaml's syntax for generics because lifetimes are a special class of generics.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#799
post #10

I wish there was a Rust-like programming language that was just a little bit higher level than Rust. I like Rust's wide ecosystem with high quality packages, the nice type system, traits, the idea that my code generally runs pretty fast even if I'm being lazy about writing good code, and my code usually working correctly if it compiles. I care about speed and correctness but Rust makes me also care about ownership an…

Pascal was almost there It puts the reference counting in the type system. Like the default string type and arrays (=vectors) are reference counted. And for speed you could use manual memory management Any string literal is like an arc . E.g. in Delphi you can now write string concatenation like: var a = 'bcd'; var b = 'xyz'; var c = a + b; which corresponds to Rust like let a = Arc::new(String::from("bcd")); let b =…

I think the big thing that hurt Pascal initially was the poor start it got off to. By the time things like Borland Pascal came around and fixed the weaknesses from explicitly starting as a teaching language, the damage had already let C pull ahead.

As for nowadays, I'd say there are three things that help people to bounce:

1. The big name (Delphi) is proprietary and Free Pascal's documentation feels like it hasn't caught up with various lessons that were learned about how to document a toolchain and standard library since the early 2000s.

(And that's before you discover that, apparently, the API documentation is manual enough that the official stance on the Free Vision TUI component's documentation is "go find a copy of the Turbo Vision book from the Borland Pascal manuals", and that the Free Pascal Wiki either neglected to mention one or two classes when they were saying what is yet to be reimplemented or neglected to mention additional restrictions present in the DPMI port.)

2. Similar to with Ada, the ecosystem people are normalized into as they learn programming is leaning more and more strongly on the C-descended syntaxes, making Wirth-style syntaxes feel more alien.

I have to admit, compared to something like Rust, there's a certain off-puttingness to having so much verbosity and ceremony in the structure of the block constructs. To exaggerate a bit to get the point across, it's sort of like Pascal expects me to remember all the layouts and lines for what an empty tax form looks like well enough to draw it from memory before filling it out... and that sense of discomfort doesn't go away if I delegate it to my code snippets tool.

It lends an ambient sense that there's an iceberg of structure I don't understand and Pascal expects me to remember how many separate peaks it should have poking out of the water and where they should be, without me understanding the topography of the submerged portion.

(And yet I still recommend it as the Java/C# equivalent for DOS retro-hobby computing, since it's safer than C and has a much richer library of bundled functionality and comparable performance.)

3. The Free Pascal APIs are aggressively 90s and don't have enough examples to break you from your 2010s-and-beyond expectations. (I was almost tearing my hair out over how to get status updates from their zip extraction code before I realized that I was fixated on the Qt/GTK/DOM/etc. idea of using some kind of signal.connect(my_callback) function rather than using subclassing to set an event handler.)

Just, in general, it's an experience that's alien to current language trends and growing more so, the documentation available before you're committed enough to pay for it is wanting, and if you're willing to pay hobbyist prices, you need to do your own research on what exists to pay for.

Re: Rust Is Hard, Or: The Misery of Mainstream Programming

#800
post #493

Earlier quoted context omitted.

Rust is really hard. So while people that don’t like Javascript still continue to use it, but people that don’t like Rust are likely to drop it like a brick.

Rust is too painful for hobby projects, IMO. Over the years, I've worked in C, C++, Go, Perl, Python, PHP, Java, Scala, JS, Tcl, ... others I've forgotten, most professionally and well as for personal projects.

Matter of taste.

I find Rust perfect for hobby projects because:

1. Squashing bugs that show up after the code successfully compiles (or, in Python's case, appears to work) is a big drain on motivation.

2. The ecosystem's focus on API stability means that, once it works the way I want, the costs of ensuring "it built/ran yesterday, so it should build/run today too" will be minimized.

3. I don't have to write as many unit tests to feel I can trust it with my data.

TL;DR: Once you're on the same wavelength as the compiler, Rust is great for projects where your motivation is purely intrinsic.

(Well, that and the compiler has been constantly improving. Things especially got much better after non-lexical lifetimes landed.)

Post reply on HN