> "macros" are probably the first thing you're taught to be afraid of (second only to "moving a picture in a Word document"),
Next time, trigger warning please! I still have PTSD from that time I tried to text flow around an image correctly back in ‘08 on deadline. I just try to think of God and country instead…
> Here, there's a conflict between the lexical scope of the function (main) and the macro (SWAP).
It might interest to some to know that GCC has a macro called __COUNTER__ (apparently also implemented by clang and MS), which auto-increments its value. You can then create something like a gensym to avoid conflict.
Here's an implementation of the "defer" keyword in C++:
X-macros in C [1] are great for doing compile-time code generation from tabular data. Especially for things like pinouts and their respective capabilities on microcontrollers, I haven't seen any other language give such a succinct, easily maintainable way of interacting and representing data such that it can be used for full function generation that an IDE can autocomplete names, types etc.
Sure there are other "newer" ways but they invariably involve so much boilerplate that you might as well just write all the code by hand.
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.
They 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.
Everything 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.
Macros 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.
Glad you liked it! If you want to learn Lisp, I'd recommend something like Racket (implementation of Scheme, a dialect of Lisp), it's a "batteries included" Lisp that should be easier for a beginner to learn. The built-in code editor (DrRacket) is, eh, good enough.
Try to visualize yourself lying in bed 5 minutes before your death. Imagine you know you're dying, set a timer, lay down, and really try to put yourself in your own shoes.
Let the panic set in, don't try to change the subject. Imagine as the seconds slip by that you struggle to reflect on all the parts of your life. 5 minutes can seem like a long time, but when it is your last few seconds they vanish quickly.
Really be in that moment. Take it seriously. Embrace the terror.
When the timer goes off none of the problems in your life will seem one-tenth as serious as before.
Only allow ones that are hygienic. Maybe also have a tool like DrRacket which will show you stage by stage what macros expand to (including features like not expanding common ones like "define" in Racket or "println!" in Rust). I think the latter in particular is important since debugging what code you're generating is very important.
It’s ok to worry, it just means you care. Find people who will worry and care with you about the same things you do and it will be feel better. Partially because you’ll find more important things to worry about, and partially because talking about it will help you cope!
Little technical nitpick: the code blocks on the linked site are unreadable without JS enabled. They have a white background & light grey text as default.
Sorry about that! I'm still trying to find a way to get good support for dark mode with a dynamic dark mode switcher, and it seems that the current one I'm using (from V8 labs) behaves... erratically when JS isn't enabled. I'm working on it!
Doing some calculations at compile time is useful. What sucks is when the language for expressing this is difficult to think about and interacts poorly with normal code.
What sucks much more is, when one cannot extend the language properly and it needs a language commitee to change anything. Or when the way to extend it is so mistake and error prone, that one cannot get it right, needs many eyes viewing it for a few years, before it becomes probably correct.
[+] [-] tomcam|3 years ago|reply
Next time, trigger warning please! I still have PTSD from that time I tried to text flow around an image correctly back in ‘08 on deadline. I just try to think of God and country instead…
[+] [-] blippage|3 years ago|reply
It might interest to some to know that GCC has a macro called __COUNTER__ (apparently also implemented by clang and MS), which auto-increments its value. You can then create something like a gensym to avoid conflict.
Here's an implementation of the "defer" keyword in C++:
It was written by gingerBill, author of the Odin programming language.[+] [-] zdimension|3 years ago|reply
[+] [-] leni536|3 years ago|reply
[+] [-] maest|3 years ago|reply
https://code.jsoftware.com/wiki/Essays/Incunabulum
[+] [-] jefftk|3 years ago|reply
[+] [-] snovv_crash|3 years ago|reply
Sure there are other "newer" ways but they invariably involve so much boilerplate that you might as well just write all the code by hand.
1. https://en.wikipedia.org/wiki/X_Macro
[+] [-] tragomaskhalos|3 years ago|reply
- 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.
[+] [-] valenterry|3 years ago|reply
See e.g.: https://gist.github.com/chrisdone/672efcd784528b7d0b7e17ad9c...
[+] [-] tialaramex|3 years ago|reply
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.
[+] [-] dataangel|3 years ago|reply
[+] [-] charlieflowers|3 years ago|reply
[+] [-] zdimension|3 years ago|reply
[+] [-] epgui|3 years ago|reply
[+] [-] klysm|3 years ago|reply
[+] [-] abrax3141|3 years ago|reply
[+] [-] teleforce|3 years ago|reply
[1] https://news.ycombinator.com/item?id=8698594
[+] [-] colordrops|3 years ago|reply
[+] [-] dotopotoro|3 years ago|reply
[+] [-] mkarliner|3 years ago|reply
[+] [-] zdimension|3 years ago|reply
[+] [-] Noler|3 years ago|reply
[+] [-] koheripbal|3 years ago|reply
Let the panic set in, don't try to change the subject. Imagine as the seconds slip by that you struggle to reflect on all the parts of your life. 5 minutes can seem like a long time, but when it is your last few seconds they vanish quickly.
Really be in that moment. Take it seriously. Embrace the terror.
When the timer goes off none of the problems in your life will seem one-tenth as serious as before.
[+] [-] slaymaker1907|3 years ago|reply
[+] [-] evanmoran|3 years ago|reply
[+] [-] unknown|3 years ago|reply
[deleted]
[+] [-] alpaca128|3 years ago|reply
[+] [-] zdimension|3 years ago|reply
[+] [-] nine_k|3 years ago|reply
I recommend both, and the punch... line made me LOL IRL.
[+] [-] unknown|3 years ago|reply
[deleted]
[+] [-] unknown|3 years ago|reply
[deleted]
[+] [-] immmmmm|3 years ago|reply
[+] [-] zdimension|3 years ago|reply
[+] [-] birdyrooster|3 years ago|reply
[+] [-] kastagg|3 years ago|reply
[+] [-] quickthrower2|3 years ago|reply
[+] [-] logdahl|3 years ago|reply
[+] [-] zelphirkalt|3 years ago|reply