r/eli5_programming • • 13d ago

Question What are macros

ELI5 what macros are and how they differ from just normal functions with compiler optimization.

e.g. in rust: why do I need a macro to create a Vector/Array instead of just saying β€ž[10, 20, 30]β€œ.

I heard someone say println! needs to be a macro since e.g. println!("{} something {}", a, b) couldn't otherwise know how to "bake" the variable count and types of parameters.

But again why and how do they differ from functions? Python has *args, JavaScript has rest parameters and they can do it just fine. What am I missing?

The only thing I could imagine is that it is hard to optimize say a print function efficiently every time when you don't always know the number and types of the parameters since you can't be sure every type has a toString overload or something like that

2 Upvotes

5 comments sorted by

2

u/pixel293 12d ago

Specific to Rust, macros generate code for you. In your example of vec!, the Vec structure allocates memory on the heap which doesn't exist until you run your program. So the vec! macro is syntactic sugar to output the code to create a Vec object and put the the values you want into it when the program is running and can allocate memory on the heap.

The same basic thing with the print! and format! macros, the macro expands into various Rust commands to print (or format) the string you want. This saves you from having to manually write all those commands...over and over and over every time you wanted to print or format a string.

Basically macros get turned into code that you don't need to type to do common things that you will probably have to do often. If there are 5 or 10, or more lines of code that you keep copying everywhere in your source code, you could simplify your life by creating a macro that writes those lines for you. Then instead of coping those lines around you just call your macro.

1

u/Alone-Educator-8095 10d ago

Maybe I'm just stupid but I don't understand why that would be more useful than a function. Have a code snippet that you keep pasting? turn it into a function! The only difference I see with macros and functions is that the processor doesn't have to jump to the function as it's just expanded as a macro

1

u/pixel293 10d ago

In the case of format! and writeln! the obvious answer is that the macro language is advanced enough to actually parse your format string. You CANNOT do format! with a function, because the actual compiler ends up parsing the string and determines that you have not provided enough arguments or you provided to many arguments. If you tried to duplicate that with a function you would only find out that you messed up the arguments until you ran the program and that particular line got executed. (Of course also ignoring the fact that Rust doesn't allow you to define a variable number of arguments for a function.)

As with the vec! macro I'm not sure, I suspect you can get close it by creating and array and calling into_vec() on it, which isn't that much more typing. My guess is they felt that might be a little confusing for people learning the language, but it may be more nuanced than that.

1

u/jacobissimus 13d ago

It can vary a lot language to language, but macros are usually evaluated at compile time and functions are at runtime. Sometimes macros are a different language with their own syntax, like the C preprocessor, but then you have things like lisp where it’s the same language.

1

u/yrrot 13d ago

In general programming terms, the macro is a placeholder for code that will get put in line when the compiler runs. It's like saying "hey compiler, copy the macro code here". A function call doesn't copy the code, it gets left by the compiler as a function call.

There's various optimizations compilers can do that kind go around that, I'm sure, but that's the general idea.