←back to thread

128 points RGBCube | 1 comments | | HN request time: 0s | source
Show context
tucnak ◴[] No.44497968[source]
A bit off-topic, but every time I read some sophisticated Rust code involving macros, I cannot help but think that something went wrong at some point. The sheer complexity far outpaces that of C++, and even though I'm sure they would call C++ on undefined behaviour (and rightfully so) it seems less of it has to do with memory and thread-safety, and moreso with good old "C++ style" bloat: pleasing all, whilst pleasing none. Rust doesn't seem worthwhile to learn, as in a few years time C++ will get memory safety proper, and I could just use that.

Maybe this is an improvement on templates and precompiler macros, but not really.

replies(4): >>44498048 #>>44498102 #>>44498299 #>>44499269 #
junon ◴[] No.44498048[source]
None of this has to do with the complexity of macros.

And no, sorry, the complexity of C++ templates far outweighs anything in Rust's macros. Templates are a turing complete extension of the type system. They are not macros or anything like it.

Rust macro rules are token-to-token transformers. Nothing more. They're also sanitary, meaning they MUST form valid syntax and don't change the semantics in weird ways like C macros can.

Proc-macros are self-standing crates with a special library type in the crate manifest indicating as such, and while they're not "sanitary" like macros rules, they're still just token to token transformers that happen to run Rust code.

Both are useful, both have their place, and only proc macros have a slight developer experience annoyance with having to expand to find syntax errors (usually not a problem though).

replies(1): >>44498432 #
codedokode ◴[] No.44498432[source]
Proc macros are implemented in an unsafe way because they run arbitrary code during compilation and access any files. I do not like it.

Also I think it would be better if they operated with reflection-like structures like functions, classes, method rather than tokens - they would be easier to write and read.

replies(2): >>44498561 #>>44499088 #
tucnak ◴[] No.44499088{3}[source]
This is often overlooked. No, I don't want random cargo package to run RCE's on my machine. And there's just so many; in terms of bloat, the dependency trees are huge, rivaled only by Nodejs, if I'm being honest. I have to build some Rust stuff once in a while (mostly Postgres extensions) and every time something goes wrong it's a nightmare to sort out.
replies(1): >>44500772 #
junon ◴[] No.44500772{4}[source]
I never have these issues. Is the postgres driver a C wrapper? that's where things tend to fall apart.
replies(1): >>44501275 #
tucnak ◴[] No.44501275{5}[source]
Yeah, they would often claim that C API is at fault, but believe it or not, blaming Rust just as much. I've had an interesting discussion with pgrx people: https://github.com/pgcentralfoundation/pgrx/issues/1897#issu... to quote @workingjubilee

> Rust has formally rejected the notion that any function can return twice. Even LLVM has no special knowledge of the name of "sigsetjmp" or "setjmp", only that some functions can return twice.

> Thus, when you call sigsetjmp or setjmp from Rust, Rust doesn't believe that you called a function that can return twice. The Rust compiler refuses to annotate it with the required LLVMIR annotation. Thus LLVM sees a call to sigsetjmp that it believes cannot return twice... it's just an ordinary function that someone named "sigsetjmp" because they have a sense of humor. What LLVM does next is between itself and whatever gods that compilers believe in, and we have no more voice in such a matter.

In this particular case, it's hardly the fault of a "C wrapper."

replies(2): >>44502152 #>>44502552 #
1. tialaramex ◴[] No.44502152{6}[source]
Sure looks like it is, indeed, a C problem. Which checks out with my experience, the only time I had a crate fail to build in all these years it was C underneath and of course C is just anything which happened to compile and seemed to work. As an ex-C programmer I guess I sympathise, none of the non-trivial C I wrote 10-20 years ago actually builds out of the box on today's systems that's just how C is, so why would Rust magically fix that.