this post was submitted on 19 Jan 2026
2 points (55.6% liked)

Rust

7695 readers
4 users here now

Welcome to the Rust community! This is a place to discuss about the Rust programming language.

Wormhole

!performance@programming.dev

Credits

  • The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)

founded 2 years ago
MODERATORS
 

Is it just me, or does Rust feel much more bare-bones than other languages? I just started learning it recently and this is the one thing that stood out to me, much more so than the memory management business. A lot of things that would normally be part of the language has to be achieved through meta-programming in Rust.

Is this a deliberate design choice? What do we gain from this setup?


Edits:

  1. Somehow, this question is being interpreted as a complaint. It's not a complaint. As a user, I don't care how the language is designed as long as it has a good user experience, but the curious part of my mind always wants to know why things are the way they are. Maybe another way to phrase my question: Is this decision to rely more on meta-programming responsible for some of the good UX we get in Rust? And if so, how?
  2. I'm using meta-programming to mean code that generates code in the original language. So if I'm programming in Rust, that would be code that generate more Rust code. This excludes compilation where Rust gets converted into assembly or any other intermediate representation.
you are viewing a single comment's thread
view the rest of the comments
[–] BB_C@programming.dev 15 points 1 week ago (1 children)

printf uses macros in its implementation.

int
__printf (const char *format, ...)
{
  va_list arg;
  int done;

  va_start (arg, format);
  done = __vfprintf_internal (stdout, format, arg, 0);
  va_end (arg);

  return done;
}

^ This is from glibc. Do you know what va_start and va_end are?

to get features that I normally achieve through regular code in other languages.

Derives expand to "regular code". You can run cargo expand to see it. And I'm not sure how that's an indication of "bare bone"-ness in any case.

Such derives are actually using a cool trick, which is the fact that proc macros and traits have separate namespaces. so #[derive(Debug)] is using the proc macro named Debug which happens to generate "regular code" that implements the Debug trait. The proc macro named Debug and implemented trait Debug don't point to the same thing, and don't have to match name-wise.

[–] RavuAlHemio@lemmy.world 7 points 1 week ago (1 children)

^ This is from glibc. Do you know what va_start and va_end are?

Does anyone? 🙃

[–] hosaka@programming.dev 5 points 6 days ago (1 children)

For functions that want to accept variadic arguments in C/Cpp

[–] RavuAlHemio@lemmy.world 6 points 6 days ago* (last edited 6 days ago) (2 children)

Yup; I was referring to their implementation being dark magic, depending on calling convention, argument type, argument order and possibly other properties specific to the processor’s instruction set…

“If you think you understand va_*, you don’t.”

[–] hosaka@programming.dev 1 points 5 days ago

Yeah, didn't catch your sarcasm there :D

[–] BB_C@programming.dev 1 points 6 days ago

I was just referring to the fact that they are macros.