4 ms·
One nice feature of Rust macros that isn't usually trumpeted is that it allows varargs to be punted out of the core language. Consider: - Varargs are, generall
by tragomaskhalos 4y ago
One nice feature of Rust macros that isn't usually trumpeted is that it allows varargs to be punted out of the core language. Consider:
- Varargs are, generally speaking, a pain and a wart, especially in statically typed languages
- Printing stuff is horribly unergonomic without varargs (C++'s iostream << is arguably a get-out here, but is widely hated),
- There are no other compelling 'mainstream' uses for varargs afaik
By having print as a macro, Rust can swerve this particular tarpit. Not suggesting that it's the reason for macroising print, but it's a welcome bonus nevertheless.
- tialaramex 4y agoEverything which needs the format-arbitrary-parameters feature in Rust is built out of macros, so yes it's the reason that println! is a macro. Even with no_std where you don't have an Allocator, and so you can't use format! to get Strings (because there aren't any Strings) you still have mechanisms built out of macros, so you could e.g. write six u16s and a f32 to the serial port on your embedded controller (you could write a &str, but since you can't allocate Strings it'll have to be some pre-defined value like "Error" or "OK"). These functions are especially tricky because we want to have a variable number of arguments with arbitrary types. We want to be able to print two bytes, a string, an array, and six different arbitrary data structures we decided were important. There are lots more applications for function(a, b, c, d, ...) where a, b, c and so on are all the same type. It might be nice to define min() and max() over these parameters for example. But cases like print-format where it's sane to choose unrelated types are rarer. Languages where I can write min("Cheese", 4, tmpfile, -Inf) have lots of other problems that outweigh the potential usefulness of such constructions. I expect that if somebody can write a sound but ergonomic varargs story for safe Rust it'll get introduced, even if they can't solve print-format it's still useful as I showed above.
- the_duke 4y agoVarargs with the same type is just a list. In many languages that could require an extra allocation, but in Rust that can just be a slice or maybe a an array with a const generic for it's size if you want to pass ownership. Varargs here would really just be a minor ergonomics improvement. Heterogeneous varargs would be more useful, but would require something like variadic generics. (which have been proposed before)
- valenterry 4y agoThey are only a wart, if the typesystem is not powerful enough (such as Rust's typesystem). With dependent types, this is a non issue. In fact, you can implement something like typesafe "printf" as a regular user-defined function in a language like Idris and to some degree even Scala. See e.g.: https://gist.github.com/chrisdone/672efcd784528b7d0b7e17ad9c115292 https://gist.github.com/chrisdone/672efcd784528b7d0b7e17ad9c...
- dataangel 4y agoMacros totally fail at keeping varargs out of core because of generics. Try writing emplace_back in Rust, or anything else that would need to generically do placement new.